Files
lingniu-vehicle-ingest/docs/operations/go-vehicle-gateway-verification-result-2026-07-01.md
2026-07-02 00:04:23 +08:00

27 KiB
Raw Blame History

Go Vehicle Gateway 旁路验证记录

验证时间2026-07-01 22:00-22:10 CST

部署版本

  • Git commit60ca42e
  • 镜像:crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-60ca42e-20260701220622
  • 部署方式ECS 115.29.187.205 上 Docker Compose 旁路部署
  • Compose 目录:/opt/lingniu-go

旁路端口和 topic

为了不影响现有 Java 生产服务,本次没有占用生产端口和生产 topic。

GB32960 旁路 TCP 115.29.187.205:23296 -> container :32960
JT808 旁路 TCP 115.29.187.205:18080 -> container :808
Realtime API 115.29.187.205:20210
GB32960 RAW topic vehicle.raw.go.gb32960.v1
JT808 RAW topic vehicle.raw.go.jt808.v1
Yutong MQTT RAW topic vehicle.raw.go.yutong-mqtt.v1
Unified topic vehicle.event.go.unified.v1

容器状态

ECS 上四个 Go 容器均已启动:

go-vehicle-gateway   Up
go-history-writer    Up
go-stat-writer       Up
go-realtime-api      Up

Kafka 验证

18080 注入 JT808 样例帧后,vehicle.raw.go.jt808.v1vehicle.event.go.unified.v1 均消费到统一 JSON envelope。

样例解析结果包含:

  • protocol=JT808
  • message_id=0x0200
  • phone=013307795425
  • longitude=121.069881
  • latitude=30.590151
  • speed_kmh=23
  • total_mileage_km=10241.2
  • 表 27 附加项 0x01 原始值 0001900C

TDengine 验证

目标库:lingniu_vehicle_ts

raw_frames count = 3
vehicle_locations count = 2
vehicle_mileage_points count = 2

最新 RAW 标识:

GB32960 | LNBSCB3D4R1234567 | LNBSCB3D4R1234567 |
JT808   | JT808:013307795425 |                    | 013307795425
JT808   | JT808:013307795425 |                    | 013307795425

说明JT808 样例 phone 当前没有在 vehicle_identity_binding 中解析到 VIN因此 TDengine tag 使用 vehicle_key=JT808:013307795425

Redis 验证

23296 注入带 VIN 的 GB32960 合成帧后Realtime API 可查询:

GET /api/realtime/vehicles/LNBSCB3D4R1234567

返回字段包含:

  • vin=LNBSCB3D4R1234567
  • protocols=["GB32960"]
  • online=true
  • speed_kmh=30
  • total_mileage_km=10000
  • soc_percent=85
  • longitude=121
  • latitude=30.56

MySQL 统计验证

23296 注入带 VIN 的 GB32960 合成帧后,vehicle_daily_metric 写入:

LNBSCB3D4R1234567 | 2020-07-01 | GB32960 | daily_mileage_km       | 0.000     | 10000.000 | 10000.000 | 1
LNBSCB3D4R1234567 | 2020-07-01 | GB32960 | daily_total_mileage_km | 10000.000 | 10000.000 | 10000.000 | 1

说明:本次 GB32960 合成帧的设备时间为测试值,因此统计日期为 2020-07-01

已修复问题

  • TDengine WebSocket 普通 INSERT 使用参数占位符时,字符串未按预期加引号,导致语法错误。已在 60ca42e 中改为显式 SQL literal 转义。
  • MySQL Go DSN 中 charset=utf8mb4%2Cutf8 会被 driver 传给 MySQL导致语法错误ECS 旁路 env 已改为 charset=utf8mb4
  • TDengine ECS 当前可用 root 密码与早先记录不一致,本次旁路 env 已按实际可认证值修正。

未完成

  • 未切换真实生产端口 32960/808
  • 未将真实外部 32960/808 流量转发到 Go 旁路端口。
  • 未开启宇通 MQTT 正式订阅。
  • JT808 样例未解析到 VIN需维护 vehicle_identity_binding 后再验证 808 每日统计。

2026-07-01 22:22 真实归档帧复验

部署版本已更新:

  • Git commit5f4f4fd
  • 镜像:crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-5f4f4fd-20260701222128

本轮补充验证内容:

  • JT808 支持 2019 版 versioned header真实帧 0x0200 可解析出 phone=14894135060longitude=117.178187latitude=30.570155speed_kmh=33.4total_mileage_km=7868.9
  • GB32960 真实燃料电池帧 VIN=LB9A32A21R0LS1707 可解析 0x01 整车、0x02 驱动电机、0x03 燃料电池、0x04 发动机、0x05 位置、0x06 极值、0x07 报警、0x08 电压、0x09 温度;后续 0x30 广东燃料电池扩展暂以 unknown raw 保留。
  • GB32960 真实帧字段包含 fuel_cell_hydrogen_consumption_kg_per_100km=1.8longitude=120.800326latitude=31.634907total_mileage_km=53490.9
  • Realtime API GET /api/realtime/vehicles/LB9A32A21R0LS1707 已返回上述经纬度和氢耗字段。
  • TDengine vehicle_locationsvehicle_mileage_points 已写入真实 GB32960 位置和里程点:
2020-07-01 08:09:22 | GB32960 | LB9A32A21R0LS1707 | lon=120.800326 | lat=31.634907 | mileage=53490.9

后续仍需补齐:

  • JT808 真实 phone 14894135060 仍未解析到 VIN需维护身份绑定后再验证 VIN 维度实时和统计。

2026-07-01 22:28 广东燃料电池扩展复验

部署版本已更新:

  • Git commita15de91
  • 镜像:crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-a15de91-20260701222743

本轮补充验证内容:

  • GB32960 真实燃料电池帧 VIN=LB9A32A21R0LS1707 的 vendor 尾部已从 unknown_unit 补为结构化块: 0x30 gd_fc_stack0x31 gd_fc_auxiliary0x32 gd_fc_dcdc0x33 gd_fc_air_conditioner0x34 gd_fc_vehicle_info0x80 gd_fc_demo_extension0x83 gd_fc_vendor_tlv
  • Kafka vehicle.raw.go.gb32960.v1 最新消息包含上述 block并输出关键扁平字段 gd_fc_stack_hydrogen_inlet_pressure_kpa=97gd_fc_stack_cell_count=108gd_fc_vehicle_hydrogen_mass_kg=4.3gd_fc_demo_stack_temp_c=65
  • Realtime API GET /api/realtime/vehicles/LB9A32A21R0LS1707 已返回 vendor 扁平字段:
gd_fc_dcdc_controller_temp_c=47
gd_fc_demo_stack_temp_c=65
gd_fc_stack_cell_count=108
gd_fc_stack_frame_cell_count=108
gd_fc_stack_hydrogen_inlet_pressure_kpa=97
gd_fc_stack_water_outlet_temp_c=65
gd_fc_vehicle_hydrogen_mass_kg=4.3
  • TDengine raw_frames 中 GB32960 行数增加到 4,最新 RAW 标识:
2026-07-01 14:28:24.869 | 172.20.0.1:47082 | GB32960 | LB9A32A21R0LS1707 | OK

后续仍需补齐:

  • JT808 真实 phone 14894135060 到 VIN 的绑定数据维护与统计复验。
  • Go 旁路尚未切换到生产 32960/808 端口;仍运行在 23296/18080

2026-07-01 22:43 JT808 前导零 phone 身份解析复验

部署版本已更新:

  • Git commit6b55694
  • 镜像:crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-6b55694-20260701224300

本轮修复内容:

  • JT808 2011 老版包头的终端手机号按 BCD[6] 解析会保留前导 0,例如包头为 013079963379
  • vehicle_identity_binding.phone 中实际维护的是去前导零后的手机号 13079963379
  • 身份解析候选键已调整为先查原始 phone再查去前导零 phone之后再按 device_idplate 降级。

真实帧复验样本:

  • 归档帧:/opt/lingniu/vehicle-ingest/gb32960/archive/2026/07/01/JT808/unknown/1782903942845000.bin
  • 消息:0x0200 位置信息汇报
  • 包头 phone013079963379
  • 绑定表 phone13079963379
  • 解析 VINLKLG7C4E3NA774736

Kafka vehicle.raw.go.jt808.v1 最新消息确认:

vin=LKLG7C4E3NA774736
phone=013079963379
parsed.header.phone_trim_zero=13079963379
parsed.identity.resolved=true
parsed.identity.source=phone
parsed.identity.value=13079963379

Realtime API 确认:

GET /api/realtime/vehicles/LKLG7C4E3NA774736

longitude=119.557997
latitude=29.049092
speed_kmh=0
total_mileage_km=0
device_time=2026-07-01T19:05:40+08:00

TDengine 确认:

raw_frames:
2026-07-01 14:49:10.913 | JT808 | LKLG7C4E3NA774736 | phone=013079963379 | message_id=512

vehicle_locations:
2026-07-01 11:05:40.000 | JT808 | LKLG7C4E3NA774736 | lon=119.557997 | lat=29.049092 | speed=0 | mileage=0

vehicle_mileage_points:
2026-07-01 11:05:40.000 | JT808 | LKLG7C4E3NA774736 | mileage=0

MySQL vehicle_daily_metric 确认:

LKLG7C4E3NA774736 | JT808 | 2026-07-01 | daily_mileage_km       | 0.000 | sample_count=1 | TOTAL_MILEAGE_DIFF
LKLG7C4E3NA774736 | JT808 | 2026-07-01 | daily_total_mileage_km | 0.000 | sample_count=1 | TOTAL_MILEAGE_DIFF

说明:该真实位置帧携带的表 27 附加项 0x01 总里程值为 0,因此本次只验证身份解析、链路落地和差值统计写入;要验证非零日里程,需要回放或等待同一 VIN 的非零总里程连续位置点。

2026-07-01 22:55 Kafka 发布重试部署复验

部署版本已更新:

  • Git commit7e7066d
  • 镜像:crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-7e7066d-20260701225503

本轮修复内容:

  • gateway 的 Kafka 发布增加同步重试封装。
  • 默认配置:
    • KAFKA_PUBLISH_ATTEMPTS=3
    • KAFKA_PUBLISH_BACKOFF_MS=100
    • KAFKA_PUBLISH_TIMEOUT_MS=3000
  • RAW 仍先于 unified event 写入RAW 写失败不会继续写 unified。
  • 单元测试覆盖首次失败后成功、重试耗尽返回错误、上下文取消时停止重试。

部署后容器状态:

go-vehicle-gateway | go-7e7066d-20260701225503 | Up
go-history-writer  | go-7e7066d-20260701225503 | Up
go-stat-writer     | go-7e7066d-20260701225503 | Up
go-realtime-api    | go-7e7066d-20260701225503 | Up

真实 808 帧回放复验:

source_endpoint=172.20.0.1:51966
protocol=JT808
message_id=0x0200
phone=013079963379
vin=LKLG7C4E3NA774736
parsed.identity.value=13079963379

Kafka vehicle.raw.go.jt808.v1 确认新消息写入partition 6 offset 从 1 增加到 2。最新消息包含:

received_at_ms=1782917751903
source_endpoint=172.20.0.1:51966
vin=LKLG7C4E3NA774736
fields.longitude=119.557997
fields.latitude=29.049092
fields.total_mileage_km=0

TDengine raw_frames 确认新 RAW 落地:

2026-07-01 14:55:51.903 | JT808 | LKLG7C4E3NA774736 | phone=013079963379 | source=172.20.0.1:51966

Realtime API 确认 Redis 已刷新:

GET /api/realtime/vehicles/LKLG7C4E3NA774736

received_at_ms=1782917751903
source_endpoint=172.20.0.1:51966
longitude=119.557997
latitude=29.049092
total_mileage_km=0

说明:当前重试层只能覆盖 Kafka 短暂抖动;如果 Kafka 长时间不可用,仍需后续增加本地磁盘 spool/WAL 和恢复补发。

2026-07-01 23:02 切换 Go 到生产 32960/808 端口

本轮操作:

  • 停止 ECS 上原有 Java Docker 容器:
    • gb32960-ingest-app
    • jt808-ingest-app
    • yutong-mqtt-app
    • vehicle-history-app
    • vehicle-analytics-app
    • vehicle-state-app
    • telemetry-field-parser-app
  • 保留 Go sidecar 和 Portainer agent。
  • 修改 /opt/lingniu-go/.env
    • GO_GB32960_TCP_PORT=32960
    • GO_JT808_TCP_PORT=808
  • Go gateway 使用镜像:
    • crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-243de5c-20260701230028
  • 开启 Kafka 本地 spool
    • host/opt/lingniu-go/spool/gateway
    • container/data/spool/gateway

端口验证:

0.0.0.0:32960 -> go-vehicle-gateway:32960
0.0.0.0:808   -> go-vehicle-gateway:808
18080/23296   -> 已释放

启动日志确认:

kafka durable spool enabled dir=/data/spool/gateway replay_interval_ms=1000
tcp listener started protocol=GB32960 addr=[::]:32960
tcp listener started protocol=JT808 addr=[::]:808

真实连接确认:

GB32960 external remote: 8.134.95.166:50084
JT808 external remote: 115.231.168.135:13801

生产 808 回放复验:

source_endpoint=172.20.0.1:54680
vin=LKLG7C4E3NA774736
phone=013079963379
longitude=119.557997
latitude=29.049092
total_mileage_km=0

TDengine 最新 RAW 复验显示生产 808 已有真实外部数据持续落地:

2026-07-01 15:03:02.960 | JT808 | LKLG7C4E1NA774802 | 013079963291 | 222.66.200.68:28394
2026-07-01 15:03:02.114 | JT808 |                  | 14894135583  | 122.152.221.156:33871
2026-07-01 15:03:01.352 | JT808 |                  | 013307795519 | 115.231.168.135:13801
2026-07-01 15:03:01.330 | JT808 | LKLG7C4E3NA774736 | 013079963379 | 222.66.200.68:28393

Kafka spool 目录确认:

/opt/lingniu-go/spool/gateway file count = 0

说明:生产 808 中仍有部分 phone 未解析出 VIN后续需要继续维护 vehicle_identity_binding 的 phone/device_id/plate 到 VIN 映射,或者增强 808 注册/鉴权帧中的 identity 回写。

2026-07-01 23:09 808 里程统计防 0 污染复验

部署版本已更新:

  • Git commitd347525
  • 镜像:crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-d347525-20260701230845

本轮修复内容:

  • stat-writer 不再把 total_mileage_km <= 0 的采样写入 MySQL 每日指标。
  • MySQL upsert 对历史 first_total_mileage_km=0 / latest_total_mileage_km=0 做纠偏;后续首次有效总里程会替换掉历史 0。
  • realtime-api 合并实时快照时,非正 total_mileage_km 不再覆盖已有正值;速度、位置、状态等其他字段仍按事件时间更新。

测试验证:

go test ./...
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/gateway
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/history-writer
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/stat-writer
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/realtime-api

生产回放验证:

  • 第一条 808 帧:device_time=2026-07-01T23:09:35+08:00total_mileage_km=12345.6
  • 第二条 808 帧:device_time=2026-07-01T23:09:36+08:00total_mileage_km=0
  • 两条帧使用同一 VINLKLG7C4E3NA774736

Redis merged 快照确认:第二条 0 里程帧没有覆盖已有有效总里程。

event_time_ms=1782918576000
source_endpoint=172.20.0.1:40946
speed_kmh=0
longitude=119.557997
latitude=29.049092
total_mileage_km=12345.6
field_times_ms.total_mileage_km=1782918575000

MySQL vehicle_daily_metric 确认0 里程采样未进入统计sample_count 只因有效总里程采样增加一次。

LKLG7C4E3NA774736 | JT808 | 2026-07-01 | daily_mileage_km       | 0.000     | sample_count=13 | first=12345.600 | latest=12345.600
LKLG7C4E3NA774736 | JT808 | 2026-07-01 | daily_total_mileage_km | 12345.600 | sample_count=13 | first=12345.600 | latest=12345.600

说明:生产 TDengine 中已经存在大量 808 非零 total_mileage_km 采样,但许多 phone 尚未映射到 VIN因此 MySQL 按 VIN 的统计只会覆盖已解析 VIN 的车辆。下一步应继续补齐 vehicle_identity_binding,让更多 808 车辆进入统计。

2026-07-01 23:23 808 注册身份自动维护复验

部署版本已更新:

  • Git commit7b44f97
  • 镜像:crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-7b44f97-20260701232200

本轮修复内容:

  • 808 0x0100 注册帧解析 provincecitymanufacturerdevice_typedevice_idplate_colorplate
  • 808 0x0102 鉴权帧解析 auth_token
  • Go gateway 在 identity resolve 后写入 jt808_registration,普通上行也会刷新 latest_seen_at
  • 注册帧通过车牌解析到 VIN 后,会尝试把 phone/device/plate 反写到 vehicle_identity_binding
  • 注册帧车牌支持 GBK 解码,避免 Incorrect string value 写入错误。

验证命令:

go test ./...
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/gateway
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/history-writer
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/stat-writer
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/realtime-api

ECS 运行状态:

go-vehicle-gateway | go-7b44f97-20260701232200 | 0.0.0.0:808->808, 0.0.0.0:32960->32960
go-history-writer  | go-7b44f97-20260701232200 | Up
go-stat-writer     | go-7b44f97-20260701232200 | Up
go-realtime-api    | go-7b44f97-20260701232200 | 0.0.0.0:20210->20210

生产日志确认:

  • 新版本启动后真实 808、32960 连接持续进入。
  • GBK 车牌注册帧不再出现 Incorrect string value

MySQL jt808_registration 确认:

registration_rows=214
distinct_phone=214
vin_rows=74
plate_rows=74
device_rows=72

013079963379 | device_id=9963379 | plate=沪A06788F | vin=LKLG7C4E3NA774736 | latest_registered_at=2026-07-01 23:23:01
013079963321 | device_id=9963321 | plate=沪A59613F | vin=LKLG7C4EXNA774796 | latest_registered_at=2026-07-01 23:23:04

说明:jt808_registration.phone 保存 808 包头原始 phonevehicle_identity_binding.phone 中已有部分去前导零 phone。Go resolver 会同时查询原始 phone 和去前导零 phone。

2026-07-01 23:28 生产链路与指标清理复验

本轮复验目标:

  • 确认 Go gateway 的 Kafka durable spool 是重启窗口残留,而不是持续发布失败。
  • 确认 stat-writer / history-writer / realtime-api 的 Kafka consumer group 无 lag。
  • 确认真实 808 车辆 registration、TDengine RAW/里程点、Redis 实时查询均在持续更新。
  • 清理之前生产合成回放产生的 JT808 当日指标测试数据。

Kafka topic / consumer group

vehicle.raw.go.jt808.v1    有持续 offset
vehicle.raw.go.gb32960.v1  有持续 offset
vehicle.event.go.unified.v1 有持续 offset

go-stat-writer    LAG=0
go-history-writer LAG=0
go-realtime-api   LAG=0

TDengine

raw_frames:
JT808   2922
GB32960 27

vehicle_mileage_points:
JT808   2050
GB32960 2

Redis 实时查询样例:

GET /api/realtime/vehicles/LKLG7C4E3NA774736
vin=LKLG7C4E3NA774736
source_endpoint=222.66.200.68:29646
plate=沪A06788F
longitude=119.556866
latitude=29.047911
total_mileage_km=12345.6

说明:该 Redis merged 快照保留了此前有效 total_mileage_km=12345.6,后续真实 808 位置帧上报的 total_mileage_km=0 不会覆盖该字段。TDengine 中该 VIN 后续真实里程点的 total_mileage_km 均为 0因此 stat-writer 按“只统计正总里程”的规则不再写 JT808 每日指标。

MySQL 指标清理:

删除前:
LKLG7C4E2NA774775 | JT808 | 2026-07-01 | daily_mileage_km       | first=0       | latest=0       | sample_count=7
LKLG7C4E2NA774775 | JT808 | 2026-07-01 | daily_total_mileage_km | first=0       | latest=0       | sample_count=7
LKLG7C4E3NA774736 | JT808 | 2026-07-01 | daily_mileage_km       | first=12345.6 | latest=12345.6 | sample_count=13
LKLG7C4E3NA774736 | JT808 | 2026-07-01 | daily_total_mileage_km | first=12345.6 | latest=12345.6 | sample_count=13

删除后等待真实流量窗口:
JT808 2026-07-01 metric rows = 0

清理原因:

  • LKLG7C4E3NA774736 的 12345.6 来自此前生产连通性合成回放,不是真实平台上报。
  • LKLG7C4E2NA774775 的 0 指标来自旧逻辑污染,当前 stat-writer 已跳过非正总里程。

Kafka spool

23:24 spool_count=904
23:25 spool_count=862
23:28 spool_count=722
new_spool_1min=0

说明spool 正在回放下降,且最近 1 分钟没有新增文件;生产 gateway 日志未见 Incorrect string value、Kafka publish error 或 replay error。

2026-07-01 23:34 每日指标查询 API 复验

部署版本已更新:

  • Git commit56f4811
  • 镜像:crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-56f4811-20260701233311

新增接口:

GET /api/stats/daily-metrics

查询参数:

vin       可选
protocol  可选GB32960 / JT808 / YUTONG_MQTT
metricKey 可选daily_mileage_km / daily_total_mileage_km
dateFrom  可选YYYY-MM-DD
dateTo    可选YYYY-MM-DD
limit     可选,默认 50最大 1000
offset    可选,默认 0

生产可访问样例:

http://115.29.187.205:20210/api/stats/daily-metrics?vin=LB9A32A21R0LS1707&protocol=GB32960&dateFrom=2020-07-01&dateTo=2020-07-01&limit=10

返回确认:

{
  "items": [
    {
      "vin": "LB9A32A21R0LS1707",
      "stat_date": "2020-07-01",
      "protocol": "GB32960",
      "metric_key": "daily_mileage_km",
      "metric_value": 0,
      "metric_unit": "km",
      "first_total_mileage_km": 53490.9,
      "latest_total_mileage_km": 53490.9,
      "sample_count": 3,
      "calculation_method": "TOTAL_MILEAGE_DIFF",
      "created_at": "2026-07-01 22:14:13",
      "updated_at": "2026-07-01 22:28:25"
    },
    {
      "vin": "LB9A32A21R0LS1707",
      "stat_date": "2020-07-01",
      "protocol": "GB32960",
      "metric_key": "daily_total_mileage_km",
      "metric_value": 53490.9,
      "metric_unit": "km",
      "first_total_mileage_km": 53490.9,
      "latest_total_mileage_km": 53490.9,
      "sample_count": 3,
      "calculation_method": "TOTAL_MILEAGE_DIFF",
      "created_at": "2026-07-01 22:14:13",
      "updated_at": "2026-07-01 22:28:25"
    }
  ],
  "limit": 10,
  "offset": 0,
  "total": 2
}

JT808 真实生产查询:

http://115.29.187.205:20210/api/stats/daily-metrics?protocol=JT808&dateFrom=2026-07-01&dateTo=2026-07-01&limit=10

返回 total=0。原因是此前合成回放产生的测试指标已清理,当前真实 808 已绑定 VIN 的车辆仍上报 total_mileage_km=0stat-writer 按规则不写非正总里程指标。

实时接口回归:

http://115.29.187.205:20210/api/realtime/vehicles/LKLG7C4E3NA774736/online

返回 online=true,说明新增 stats API 没有影响 Redis 实时查询。

发布后 spool 观察:

发布后立即spool_count=1101new_spool_1min=102
等待 60 秒spool_count=1033new_spool_1min=0

说明:本次发布重启窗口产生的 spool 正在回放下降,且最近 1 分钟没有新增gateway/realtime-api 最近日志未见 error、failed、Kafka publish error。

2026-07-01 23:50 生产端口接管与 RAW 查询 API 复验

部署版本:

  • Git commit5937132
  • 镜像:crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-5937132-20260701234220

生产端口状态:

go-vehicle-gateway 0.0.0.0:808->808/tcp
go-vehicle-gateway 0.0.0.0:32960->32960/tcp

旧 Java 容器状态:

gb32960-ingest-app              restart=no status=exited
jt808-ingest-app                restart=no status=exited
yutong-mqtt-app                 restart=no status=exited
vehicle-history-app             restart=no status=exited
vehicle-analytics-app           restart=no status=exited
vehicle-state-app               restart=no status=exited
telemetry-field-parser-app      restart=no status=exited

生产连接确认:

  • JT808 端口 808 已收到外部连接:222.66.200.68115.231.168.135
  • GB32960 端口 32960 已收到外部连接:8.134.95.166117.160.0.65
  • ECS 当前没有 8089 监听。

RAW 查询 API

GET /api/history/raw-frames

生产可访问样例:

http://115.29.187.205:20210/api/history/raw-frames?protocol=JT808&vin=LKLG7C4E3NA774736&messageId=0x0200&limit=1
http://115.29.187.205:20210/api/history/raw-frames?protocol=GB32960&vin=LB9A32A21R0LS1707&limit=1

接口复验结果:

JT808_RAW:
total=1
protocol=JT808
vin=LKLG7C4E3NA774736
phone=013079963379
message_id=512
message_id_hex=0x0200
parse_status=OK
raw_hex_len=94
parsed_json_len=651
fields_json_len=186

GB32960_RAW:
total=1
protocol=GB32960
vin=LB9A32A21R0LS1707
message_id=2
message_id_hex=0x0002
parse_status=OK
raw_hex_len=1548
parsed_json_len=3698
fields_json_len=563

同轮回归验证:

GET /api/realtime/vehicles/LKLG7C4E3NA774736/online
online=true
protocols=["JT808"]

GET /api/stats/daily-metrics?vin=LB9A32A21R0LS1707&protocol=GB32960&dateFrom=2020-07-01&dateTo=2026-07-01&limit=1
total=1
protocol=GB32960
metric_key=daily_mileage_km
calculation_method=TOTAL_MILEAGE_DIFF

说明:

  • RAW 查询已返回 raw_hexparsed_jsonfields_json,可以用于查看完整解析结果。
  • 日统计和实时查询在生产端口接管后仍可用。

2026-07-02 00:00 原生 systemd 部署与宇通 MQTT 复验

根据本次 goal 的新要求Go 接入链路后续不再使用 Docker 部署。本轮已中断 Docker 镜像构建路径,改为 ECS 原生 Linux 二进制 + systemd。

部署版本:

  • Git commit594ab2d
  • 部署目录:/opt/lingniu-go-native
  • 当前 release/opt/lingniu-go-native/releases/594ab2d
  • 当前指针:/opt/lingniu-go-native/current -> /opt/lingniu-go-native/releases/594ab2d

systemd 服务:

lingniu-go-gateway.service        active
lingniu-go-history-writer.service active
lingniu-go-stat-writer.service    active
lingniu-go-realtime-api.service   active

端口确认:

[::]:32960  gateway
[::]:808    gateway
[::]:20210  realtime-api

Go Docker 容器已停止:

go-vehicle-gateway  Exited
go-history-writer   Exited
go-stat-writer      Exited
go-realtime-api     Exited

宇通 MQTT

yutong mqtt client started
mqtt subscribed broker=ssl://cpxlm.axxc.cn:38883 topic=/ytforward/shln/+ qos=1

说明MQTT broker 存在短连接 EOF 后自动重连现象,但订阅后已收到真实数据并落 RAW。

RAW 查询复验:

GET /api/history/raw-frames?protocol=YUTONG_MQTT&limit=3

total=3
protocol=YUTONG_MQTT
vin=LMRKH9AC1R1004131
vehicle_key=LMRKH9AC1R1004131
parse_status=OK
parsed_json_len=1104
fields_json_len=116

同轮回归:

GET /api/history/raw-frames?protocol=JT808&vin=LKLG7C4E3NA774736&messageId=0x0200&limit=1
total=1
parse_status=OK

GET /api/history/raw-frames?protocol=GB32960&vin=LB9A32A21R0LS1707&limit=1
total=1
parse_status=OK

GET /api/realtime/vehicles/LKLG7C4E3NA774736/online
online=true
protocols=["JT808"]

本轮落地文件:

  • deploy/systemd/README.md
  • deploy/systemd/lingniu-go-gateway.service
  • deploy/systemd/lingniu-go-history-writer.service
  • deploy/systemd/lingniu-go-stat-writer.service
  • deploy/systemd/lingniu-go-realtime-api.service

2026-07-02 00:04 宇通 MQTT EOF 诊断

现象:

Go 原生部署后,lingniu-go-gateway 日志中出现多次:

mqtt connection lost error=EOF
mqtt connection lost error=write: broken pipe
mqtt subscribed topic=/ytforward/shln/+ qos=1

10 分钟窗口统计:

mqtt subscribed = 33
mqtt connection lost = 32

对照旧 Java yutong-mqtt-app 历史日志,停止前也存在同类行为:

mqtt endpoint [yutong] received topic=/ytforward/shln/1 bytes=574
mqtt endpoint [yutong] connection lost
Caused by: java.io.EOFException
mqtt endpoint [yutong] re-subscribed topic=/ytforward/shln/+ qos=1
mqtt endpoint [yutong] received topic=/ytforward/shln/3 bytes=586

判断:

  • EOF/短连接不是 Go TLS 支持或 systemd 原生部署新引入的问题。
  • 旧 Java 和新 Go 都表现为订阅、收到数据、broker 断开、自动重连。
  • 当前链路可持续收到宇通 MQTT 数据并写入 TDengine RAW。

复验:

GET /api/history/raw-frames?protocol=YUTONG_MQTT&limit=1

total=1
protocol=YUTONG_MQTT
vin=LMRKH9ACXR1004094
parse_status=OK
parsed_json_len=1080
fields_json_len=115

运维建议:

  • 单条 EOF 不作为不可用判断。
  • YUTONG_MQTT RAW 入库增长、最近成功 mqtt subscribed 时间、服务 systemctl is-active 作为可用性判断。
  • 如果 EOF 频率继续升高且 RAW 不再增长,再联系宇通侧确认 broker 长连接策略、同一 clientId 并发限制或网络出口策略。