Dart 和 InfluxDB 入门

导航至

本文由 Habdul Hazeez 撰写。向下滚动查看作者的照片和简介。

您刚刚启动了应用程序,它吸引了超出您预期的用户。您的 Web 服务器被数据淹没。现在您需要更多了解您的用户:他们主要使用什么设备,以及他们在应用程序上停留多长时间?

时间序列数据库将帮助您回答这些问题。它允许您在指定的时间段内保存给定点的数据,从而使您深入了解您获得的使用类型和时间。

其中一个时间序列数据库是 InfluxDB。本教程将向您展示如何使用 Dart 应用程序设置 InfluxDB。

什么是时间序列数据库?

时间序列数据库旨在存储和检索在给定时间段内收集的关于测量或事件的时间戳数据。此信息可以帮助您跟踪和分析该数据的变化。

时间序列数据的常见使用案例

以下是时间序列数据库的一些值得注意的使用案例,具体取决于您的时间戳数据的性质和来源

  • 了解股票市场交易
  • 根据房价上涨或下跌计划房地产投资
  • 跟踪和优化用电量
  • 通过传感器监控物联网 (IoT) 设备的性能
  • 为什么使用 InfluxDB

InfluxDB 是市场上更知名的时间序列数据库之一。它快速且易于使用,没有依赖项。它提供多种数据压缩算法,并与开源 Telegraf 插件配合使用,提供更好的开发者体验 (DX)。

安装 InfluxDB

访问下载页面进行安装。您可以选择注册您的下载。如果您喜欢无需本地安装的 InfluxDB 托管云实例,也可以使用InfluxDB Cloud

选择您的平台并按照说明进行操作。本教程使用 Windows;如果您也选择 Windows,则需要 wget。有关如何在 MacOS 或 Linux 上安装 InfluxDB 的完整说明,您可以查看文档

Download command for Windows

使用管理员权限启动 PowerShell,并粘贴命令进行下载。InfluxDB 文件将出现在您的 C:\ 目录中。

InfluxDB downloaded archive

将 InfluxDB 解压缩到文件夹中。在本例中,它是 Program Files 目录中的一个名为 InfluxData 的文件夹

# Extract InfluxDB download archive
Expand-Archive .\influxdb2-2.0.9-windows-amd64.zip -DestinationPath 'C:\Program Files\InfluxData\influxdb\'

完成后,InfluxDB 和关联文件将位于与安装文件同名的文件夹中。选择此文件夹中的所有文件,并将它们移动到上层目录。您的文件夹结构应与此类似

Folder-structure

切换回 PowerShell 并导航到 InfluxDB 目录。使用命令 ./influxd 启动 InfluxDB 守护程序

InfluxDB launch

在浏览器中访问 localhost:8086。您将看到 onboarding 页面

Onboarding page in Firefox 93

单击“开始”设置您的帐户

Account-setup-page

单击“继续”,然后选择“快速启动”。系统将提示您输入之前创建的登录详细信息

Login page

输入您的登录详细信息以进入您的仪表板

InfluxDB dashboard

当您从您的应用程序与 InfluxDB 交互时,您将需要一个令牌。您可以在“数据”>“令牌”下找到它

Authentication token

接下来您将安装 InfluxDB 客户端库,但首先您需要一些先决条件。

客户端库的先决条件

以下是安装客户端库所需执行的操作

  • 安装包管理器
  • 安装 Dart SDK
  • 创建项目文件夹

安装包管理器

在 Linux 上,使用您发行版的包管理器。对于 macOS,安装 Homebrew

在本教程中,您将在 Windows 上使用 Chocolatey(这也需要 PowerShell)。

Chocolatey installation

安装 Dart SDK

使用管理员权限启动命令提示符并安装 Dart SDK

choco install dart-sdk

Dart SDK installation

创建项目文件夹

切换回命令行并导航到您喜欢的文件夹。键入并执行以下命令

dart create test-app

下图显示了代码的实际效果

Creation of project folder

设置客户端库

该库适用于 InfluxDB 版本 2 及更高版本。它可以在 pub.dev 包存储库中下载。

InfluxDB client library download page

在您的项目目录中打开 PowerShell。键入以下命令

# InfluxDB client installation
dart pub add influxdb_client

InfluxDB client installation

要确认它已安装,请检查您的 pubspec.yaml 文件并确保它被列为依赖项

InfluxDB client library installation in pubspec.yaml file

将客户端库连接到 InfluxDB

在此阶段,您将开始编写一些代码。如果您尚未安装 VS Code,请安装它;它提供了大量的扩展,包括 Dart 扩展。

通过 VS Code 扩展市场安装扩展

Dart tool installed in VS Code

创建并保存一个新的 Dart 文件。将其命名为 main.dart 并插入以下代码

// @dart=2.9

import 'package:influxdb_client/api.dart';

void main() async {
  var client = InfluxDBClient(
  	url: 'http://localhost:8086',
  	token:
      	'Your token here',
  	org: 'Your org name',
  	bucket: 'Your bucket name',
  	debug: true);

  var healthCheck = await client.getHealthApi().getHealth();
  print(
  	'Health check: ${healthCheck.name}/${healthCheck.version} - ${healthCheck.message}');
    
  client.close();
}

单击 main 函数正上方的“运行”以执行代码

Successful connection

您可以使用 HTTPS 改进连接。

通过 HTTPS 连接客户端库

在连接库之前,您需要通过 HTTPS 运行 InfluxDB。在继续之前关闭 InfluxDB。

现在使用证书和密钥对启动 InfluxDB。由于您在本地计算机上,因此您将创建一个自签名证书和密钥。

您可以通过两种方式执行此操作

  • 使用在线服务
  • 使用 OpenSSL 库

本教程采用后一种选择。您可以在此处的 GitHub gist 找到完整详细信息。

使用自签名证书和密钥重启 InfluxDB

./influxd --tls-cert="C:\Program Files\OpenSSL-Win64\bin\SSL\influxdb-selfsigned.crt" --tls-key="C:\Program Files\OpenSSL-Win64\bin\SSL\influxdb-selfsigned.key"

检查命令提示符(或终端)中的连接字符串。它应显示 https

HTTPS connection

切换回 VS Code。在 InfluxDB 通过 HTTPS 运行时,客户端库尝试通过 HTTP 连接的任何尝试都不会通过。相反,您将看到错误消息 Client sent an HTTP request to an HTTPS server

InfluxDB application error 400

仅更改协议 https:// 无法解决此问题。您将收到另一个错误

Self-signed certificate error

解决方法是导入 dart:io 并在您的 main() 函数之前创建一个类。它授予您使用自签名证书的权限。在 main() 函数中使用该类。有关更多详细信息,请查看 此处

// @dart=2.9

import 'dart:io';

import 'package:influxdb_client/api.dart';

class DevHttpOverrides extends HttpOverrides {
  @override
  HttpClient createHttpClient(SecurityContext context) {
	return super.createHttpClient(context)
  	..badCertificateCallback =
      	(X509Certificate cert, String host, int port) => true;
  }
}

void main() async {
  HttpOverrides.global = DevHttpOverrides();

  var client = InfluxDBClient(
  	url: 'https://localhost:8086',
  	token:
      	'Your token here',
  	org: 'Your org name',
  	bucket: 'Your bucket name',
  	debug: true);

  var healthCheck = await client.getHealthApi().getHealth();
  print(
  	'Health check: ${healthCheck.name}/${healthCheck.version} - ${healthCheck.message}');
 
  client.close();
}

重启连接,一切都应该正常。

Successful HTTPS connection

将数据插入 InfluxDB

您将在 influx_data_NOT_annotated.csv 中找到要使用的数据。就在这里

{
  "measurement": "watt-hour",
  "tags": [
    "house_name": "The Johnsons"
  ],
  "fields": [
    "electricity_consumption": 78
  ]
}

write_data.dart 代码执行插入操作

// @dart=2.9
import 'dart:io';
import 'package:influxdb_client/api.dart';

class DevHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext context) {
    return super.createHttpClient(context)
    ..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
  }
}

void main() async {
    HttpOverrides.global = DevHttpOverrides(); 
    var client = InfluxDBClient(
        url: 'https://localhost:8086',
        token: 'Your token here',
        org: 'Your org name',
        bucket: 'Your bucket name', 
debug: true);
var writeApi = client.getWriteService(WriteOptions().merge(
        precision: WritePrecision.s, 
        batchSize: 100,
        flushInterval: 5000,
        gzip: true));

var point = Point('watt-hour')
    .addTag('house_name', 'The Johnsons') 
    .addField('electricity_consumption', 78) 
    .time(DateTime.now().toUtc());

await writeApi.write(point).then((value) {
    print('Write completed 1'); 
}).catchError((exception) {
    print(exception);  });

client.close();

}

您将在调试控制台中看到 Write completed 1

从 InfluxDB 读取数据

读取数据涉及以下步骤

  • 启动连接
  • 启动库提供的 getQuery 服务
  • 使用 Flux 查询来过滤数据
  • 迭代记录
  • 打印记录
// @dart=2.9
import 'dart:async';
import 'dart:io';
import 'package:influxdb_client/api.dart';
class DevHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext context) {
    return super.createHttpClient(context)
    ..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
  }
}

void main() async {
    HttpOverrides.global = DevHttpOverrides();
    var client = InfluxDBClient(
         url: 'https://localhost:8086',
         token: 'Your token here', 
        org: 'Your org name', 
        bucket: 'Your bucket name', 
        debug: true);

 // Reading the data
var queryService = client.getQueryService();

var fluxQuery = '''
from(bucket: "test_bck")
|> range(start: -1d) 
|> filter(fn: (r) => r["_measurement"] == "watt-hour") 
|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
|> yield(name: "mean")  ''';

// query to stream and iterate all records  var count = 0;  var recordStream = await queryService.query(fluxQuery);

await recordStream.forEach((record) {
    print( 'record: ${count++} ${record['_time']}: ${record['_field']} ${record['house_name']} ${record['_value']}');  });

client.close();}

有关读取数据的其他选项,请查看 query_data.dart。这些选项是 Raw CSV 和 StreamSubscription。

更新 InfluxDB 数据

您还可以更新存储在 InfluxDB 中的数据,但应注意,在使用时间序列数据库时,更新数据通常被认为是不良做法。

要更新数据,您需要与点关联的标签名称。

本教程使用了名称 Mavericks 的数据

Data for Mavericks

Mavericks 的用电量已更新为 178

// code truncated to save space

void main() async {

// code truncated to save space

var point = Point('watt-hour')
.addTag('house_name', 'Mavericks')
.addField('electricity_consumption', 178)
.time(DateTime.now().toUtc());

 // code truncated to save space}

因此,它反映在数据库中。

Updated data for Mavericks

您将在此 GitHub 存储库中找到完整代码。

库最佳实践

以下是客户端库应遵循的一些最佳实践

  • 连接到数据库时使用 SSL/TLS
  • 从其 pub.dev 存储库安装库
  • 尽可能更新它

结论

现在您应该对如何通过 Dart 应用程序使用 InfluxDB 有了更好的了解。InfluxDB 提供的数据可以使您深入了解应用程序的用户和流量类型,从而帮助您为您的业务做出明智的决策。

有关 InfluxDB 的更多信息,请查看此处的文档

关于作者

Habdul Hazeez 通过代码和文字表达自己。他是 Dev.to、Educative edpresso 和 CSS-Tricks 的技术作家。他之前曾在 LogRocket 博客工作。