写入 InfluxDB v2.x 必须使用 WriteAPI,不可直接用 http.Client 发送 POST 请求;需初始化 Client、获取 WriteAPI 实例、用 WritePoint/WriteRecord 提交,其自动处理 batching、retry、gzip 和 precision 对齐。

写入 InfluxDB v2.x 时必须用 WriteAPI,不是 http.Client 直发
go 官方 client 库(influxdb-client-go)不支持直接构造 HTTP 请求体写入;自己拼 POST /api/v2/write 很容易丢时间戳、乱编码、漏 precision 参数,导致数据写入失败或时间错位。
正确路径是:初始化 Client → 获取 WriteAPI 实例 → 用 WritePoint 或 WriteRecord 提交。
-
WriteAPI自动处理 batching、retry、gzip、precision 对齐(比如你传time.Now(),它会按你配置的precision截断) - 别在循环里反复调用
client.WriteAPI(...)—— 每次都新建 API 实例会泄漏 goroutine - 写入前务必确认 bucket 名和 org ID 正确,错误时返回的
404 Not Found不提示具体缺哪个,容易卡住排查
Point 构造时 tag 和 field 必须严格区分,混用会导致字段类型冲突
InfluxDB 的 line protocol 要求 tag 是索引键(String),field 是值(可为 Float/int/bool/string),同一 field 名后续写入不同类型(比如先写 temp=23.5,再写 temp="unknown")会报 field type conflict 错误,且该 series 将被锁定无法再写。
- tag 只能是 string,且建议控制在 10 个以内,过多影响查询性能
- 数值类数据一律进 field,即使它是设备 ID(如
device_id=123i)也要加i后缀标整型,否则默认当 float 存 - 避免用空格、逗号、等号在 tag/field 值里出现——它们是 line protocol 的保留符,不转义会解析失败
示例:
p := influxdb2.NewPoint("cpu", map[string]string{"host": "srv01", "region": "cn-east"}, map[string]interface{}{"usage_user": 23.4, "core_count": 8i}, time.Now())
立即学习“go语言免费学习笔记(深入)”;
批量写入要设 batchSize 和 flushInterval,别依赖默认值
默认 batchSize=1000、flushInterval=1s,对 iot 场景太激进:高频小设备(如每秒 1 条温湿度)可能攒不满 batch 就超时 flush,而低频设备(如每 5 分钟上报)可能一直不触发写入。
- IoT 场景建议设
batchSize=200+flushInterval=500ms,平衡延迟与吞吐 - 若用
WriteAPIBlocking(同步写),flushInterval无效,每次WritePoint都直发,性能差但可控,适合调试 - 注意
WriteAPI内部有缓冲队列,如果程序 exit 前没调Close(),最后一部分点大概率丢失
时区和时间精度不匹配会让数据“看起来没写进去”
Go 的 time.Time 默认带本地时区,但 InfluxDB v2 存储的是 UTC 时间戳;如果你用 time.Now() 写入,又在 ui 里选了东八区查看,但没开「自动转换时区」,数据会显示成 8 小时前,误以为写失败。
- 写入前统一转 UTC:
time.Now().UTC(),比依赖客户端时区更可靠 - precision 设错(比如服务端配
ms,代码传s)会导致时间戳被截断到秒级,多个点挤在同一毫秒,排序混乱 - 查询时用
now() - 1h查不到刚写的点?检查 InfluxDB server 的系统时间是否和你的 Go 服务一致——NTP 不同步是 IoT 环境常见盲点
写 InfluxDB 最容易被忽略的,是 WriteAPI.Close() 调用时机和 bucket/org 权限粒度。很多问题不是代码逻辑错,而是资源没释放完、权限只给了读没给写、或者时间戳单位和服务端配置对不上。