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

835 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Go Vehicle Gateway 旁路验证记录
验证时间2026-07-01 22:00-22:10 CST
## 部署版本
- Git commit`60ca42e`
- 镜像:`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 容器均已启动:
```text
go-vehicle-gateway Up
go-history-writer Up
go-stat-writer Up
go-realtime-api Up
```
## Kafka 验证
`18080` 注入 JT808 样例帧后,`vehicle.raw.go.jt808.v1`
`vehicle.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`
```text
raw_frames count = 3
vehicle_locations count = 2
vehicle_mileage_points count = 2
```
最新 RAW 标识:
```text
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 可查询:
```text
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` 写入:
```text
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 commit`5f4f4fd`
- 镜像:`crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-5f4f4fd-20260701222128`
本轮补充验证内容:
- JT808 支持 2019 版 versioned header真实帧 `0x0200` 可解析出 `phone=14894135060``longitude=117.178187``latitude=30.570155``speed_kmh=33.4``total_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.8``longitude=120.800326``latitude=31.634907``total_mileage_km=53490.9`
- Realtime API `GET /api/realtime/vehicles/LB9A32A21R0LS1707` 已返回上述经纬度和氢耗字段。
- TDengine `vehicle_locations``vehicle_mileage_points` 已写入真实 GB32960 位置和里程点:
```text
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 commit`a15de91`
- 镜像:`crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-a15de91-20260701222743`
本轮补充验证内容:
- GB32960 真实燃料电池帧 `VIN=LB9A32A21R0LS1707` 的 vendor 尾部已从 `unknown_unit` 补为结构化块:
`0x30 gd_fc_stack``0x31 gd_fc_auxiliary``0x32 gd_fc_dcdc``0x33 gd_fc_air_conditioner`
`0x34 gd_fc_vehicle_info``0x80 gd_fc_demo_extension``0x83 gd_fc_vendor_tlv`
- Kafka `vehicle.raw.go.gb32960.v1` 最新消息包含上述 block并输出关键扁平字段
`gd_fc_stack_hydrogen_inlet_pressure_kpa=97``gd_fc_stack_cell_count=108`
`gd_fc_vehicle_hydrogen_mass_kg=4.3``gd_fc_demo_stack_temp_c=65`
- Realtime API `GET /api/realtime/vehicles/LB9A32A21R0LS1707` 已返回 vendor 扁平字段:
```text
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 标识:
```text
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 commit`6b55694`
- 镜像:`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_id``plate` 降级。
真实帧复验样本:
- 归档帧:`/opt/lingniu/vehicle-ingest/gb32960/archive/2026/07/01/JT808/unknown/1782903942845000.bin`
- 消息:`0x0200` 位置信息汇报
- 包头 phone`013079963379`
- 绑定表 phone`13079963379`
- 解析 VIN`LKLG7C4E3NA774736`
Kafka `vehicle.raw.go.jt808.v1` 最新消息确认:
```text
vin=LKLG7C4E3NA774736
phone=013079963379
parsed.header.phone_trim_zero=13079963379
parsed.identity.resolved=true
parsed.identity.source=phone
parsed.identity.value=13079963379
```
Realtime API 确认:
```text
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 确认:
```text
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` 确认:
```text
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 commit`7e7066d`
- 镜像:`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。
- 单元测试覆盖首次失败后成功、重试耗尽返回错误、上下文取消时停止重试。
部署后容器状态:
```text
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 帧回放复验:
```text
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`。最新消息包含:
```text
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 落地:
```text
2026-07-01 14:55:51.903 | JT808 | LKLG7C4E3NA774736 | phone=013079963379 | source=172.20.0.1:51966
```
Realtime API 确认 Redis 已刷新:
```text
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`
端口验证:
```text
0.0.0.0:32960 -> go-vehicle-gateway:32960
0.0.0.0:808 -> go-vehicle-gateway:808
18080/23296 -> 已释放
```
启动日志确认:
```text
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
```
真实连接确认:
```text
GB32960 external remote: 8.134.95.166:50084
JT808 external remote: 115.231.168.135:13801
```
生产 `808` 回放复验:
```text
source_endpoint=172.20.0.1:54680
vin=LKLG7C4E3NA774736
phone=013079963379
longitude=119.557997
latitude=29.049092
total_mileage_km=0
```
TDengine 最新 RAW 复验显示生产 808 已有真实外部数据持续落地:
```text
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 目录确认:
```text
/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 commit`d347525`
- 镜像:`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` 不再覆盖已有正值;速度、位置、状态等其他字段仍按事件时间更新。
测试验证:
```text
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:00``total_mileage_km=12345.6`
- 第二条 808 帧:`device_time=2026-07-01T23:09:36+08:00``total_mileage_km=0`
- 两条帧使用同一 VIN`LKLG7C4E3NA774736`
Redis merged 快照确认:第二条 0 里程帧没有覆盖已有有效总里程。
```text
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 只因有效总里程采样增加一次。
```text
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 commit`7b44f97`
- 镜像:`crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-7b44f97-20260701232200`
本轮修复内容:
- 808 `0x0100` 注册帧解析 `province``city``manufacturer``device_type``device_id``plate_color``plate`
- 808 `0x0102` 鉴权帧解析 `auth_token`
- Go gateway 在 identity resolve 后写入 `jt808_registration`,普通上行也会刷新 `latest_seen_at`
- 注册帧通过车牌解析到 VIN 后,会尝试把 phone/device/plate 反写到 `vehicle_identity_binding`
- 注册帧车牌支持 GBK 解码,避免 `Incorrect string value` 写入错误。
验证命令:
```text
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 运行状态:
```text
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` 确认:
```text
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 包头原始 phone`vehicle_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
```text
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
```text
raw_frames:
JT808 2922
GB32960 27
vehicle_mileage_points:
JT808 2050
GB32960 2
```
Redis 实时查询样例:
```text
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 指标清理:
```text
删除前:
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
```text
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 commit`56f4811`
- 镜像:`crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-56f4811-20260701233311`
新增接口:
```text
GET /api/stats/daily-metrics
```
查询参数:
```text
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
```
生产可访问样例:
```text
http://115.29.187.205:20210/api/stats/daily-metrics?vin=LB9A32A21R0LS1707&protocol=GB32960&dateFrom=2020-07-01&dateTo=2020-07-01&limit=10
```
返回确认:
```json
{
"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 真实生产查询:
```text
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=0`stat-writer 按规则不写非正总里程指标。
实时接口回归:
```text
http://115.29.187.205:20210/api/realtime/vehicles/LKLG7C4E3NA774736/online
```
返回 `online=true`,说明新增 stats API 没有影响 Redis 实时查询。
发布后 spool 观察:
```text
发布后立即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 commit`5937132`
- 镜像:`crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-5937132-20260701234220`
生产端口状态:
```text
go-vehicle-gateway 0.0.0.0:808->808/tcp
go-vehicle-gateway 0.0.0.0:32960->32960/tcp
```
旧 Java 容器状态:
```text
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.68``115.231.168.135`
- GB32960 端口 `32960` 已收到外部连接:`8.134.95.166``117.160.0.65`
- ECS 当前没有 `8089` 监听。
RAW 查询 API
```text
GET /api/history/raw-frames
```
生产可访问样例:
```text
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
```
接口复验结果:
```text
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
```
同轮回归验证:
```text
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_hex``parsed_json``fields_json`,可以用于查看完整解析结果。
- 日统计和实时查询在生产端口接管后仍可用。
## 2026-07-02 00:00 原生 systemd 部署与宇通 MQTT 复验
根据本次 goal 的新要求Go 接入链路后续不再使用 Docker 部署。本轮已中断 Docker 镜像构建路径,改为 ECS 原生 Linux 二进制 + systemd。
部署版本:
- Git commit`594ab2d`
- 部署目录:`/opt/lingniu-go-native`
- 当前 release`/opt/lingniu-go-native/releases/594ab2d`
- 当前指针:`/opt/lingniu-go-native/current -> /opt/lingniu-go-native/releases/594ab2d`
systemd 服务:
```text
lingniu-go-gateway.service active
lingniu-go-history-writer.service active
lingniu-go-stat-writer.service active
lingniu-go-realtime-api.service active
```
端口确认:
```text
[::]:32960 gateway
[::]:808 gateway
[::]:20210 realtime-api
```
Go Docker 容器已停止:
```text
go-vehicle-gateway Exited
go-history-writer Exited
go-stat-writer Exited
go-realtime-api Exited
```
宇通 MQTT
```text
yutong mqtt client started
mqtt subscribed broker=ssl://cpxlm.axxc.cn:38883 topic=/ytforward/shln/+ qos=1
```
说明MQTT broker 存在短连接 `EOF` 后自动重连现象,但订阅后已收到真实数据并落 RAW。
RAW 查询复验:
```text
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
```
同轮回归:
```text
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`