fix: support tdengine gb32960 raw queries
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
lingniu
2026-06-29 20:19:44 +08:00
parent 12de83e37f
commit 80e96d8075
13 changed files with 398 additions and 51 deletions

View File

@@ -5,7 +5,7 @@
1. 协议 App 接收 TCP 报文。
2. 协议 App 归档原始帧元数据,并把事件信封发布到 Kafka。
3. `vehicle-history-app` 消费 Kafka。
4. history 写入 raw、locationtelemetry field 到 TDengine
4. history 写入 raw、location 到 TDengine按需开启 telemetry field 逐字段宽表
5. Swagger/API 通过 TDengine 做历史分页查询。
每一步都必须执行命令并检查输出后,才能标记为已验证。
@@ -17,15 +17,21 @@
```bash
export KAFKA_BROKERS=114.55.58.251:9092
export TDENGINE_HISTORY_ENABLED=true
export TDENGINE_JDBC_URL='jdbc:TAOS-RS://<tdengine-host>:6041/vehicle_history'
export TDENGINE_HISTORY_DATABASE=vehicle_ts
export TDENGINE_JDBC_URL='jdbc:TAOS-WS://<tdengine-host>:6041/vehicle_ts'
export TDENGINE_DRIVER_CLASS_NAME=com.taosdata.jdbc.ws.WebSocketDriver
export TDENGINE_USERNAME=root
export TDENGINE_PASSWORD='<tdengine-password>'
export TDENGINE_MIN_IDLE=0
export TDENGINE_MAX_POOL_SIZE=32
export EVENT_FILE_STORE_ENABLED=false
export TDENGINE_TELEMETRY_FIELDS_ENABLED=false
```
`TDENGINE_MIN_IDLE=0` 用于减少冷启动时 TDengine 连接重试日志。TDengine 地址稳定后,再按生产并发调大连接池。
高吞吐生产验收默认关闭 `EVENT_FILE_STORE_ENABLED``TDENGINE_TELEMETRY_FIELDS_ENABLED`,验证 `raw_frames``vehicle_locations`、raw archive 文件和分页查询闭环。GB32960 snapshot/fields 接口会通过 TDengine `raw_frames` 索引找到 `rawUri`,再回读共享 archive 的原始 `.bin` 即时解析;需要兼容旧 `/api/event-history/records` 低层记录接口或逐字段趋势宽表时,再显式开启对应开关,并单独压测写入放大。
## 构建
```bash
@@ -41,7 +47,7 @@ mvn -pl modules/apps/jt808-ingest-app,modules/apps/gb32960-ingest-app,modules/ap
## 启动 JT808 接入服务,监听 808 端口
```bash
HTTP_PORT=20400 \
HTTP_PORT=20482 \
JT808_PORT=808 \
KAFKA_CONSUMER_ENABLED=false \
java -jar modules/apps/jt808-ingest-app/target/jt808-ingest-app.jar
@@ -50,7 +56,7 @@ java -jar modules/apps/jt808-ingest-app/target/jt808-ingest-app.jar
验证:
```bash
curl -sS http://127.0.0.1:20400/actuator/health
curl -sS http://127.0.0.1:20482/actuator/health
lsof -nP -iTCP:808 -sTCP:LISTEN
```
@@ -77,8 +83,9 @@ lsof -nP -iTCP:32960 -sTCP:LISTEN
```bash
HTTP_PORT=20200 \
KAFKA_CONSUMER_ENABLED=true \
EVENT_FILE_STORE_ENABLED=true \
EVENT_FILE_STORE_ENABLED=false \
EVENT_FILE_STORE_PATH=./target/tdengine-verification/event-store \
TDENGINE_TELEMETRY_FIELDS_ENABLED=false \
SINK_ARCHIVE_PATH=./target/tdengine-verification/archive \
java -jar modules/apps/vehicle-history-app/target/vehicle-history-app.jar
```
@@ -88,10 +95,10 @@ java -jar modules/apps/vehicle-history-app/target/vehicle-history-app.jar
```bash
curl -sS http://127.0.0.1:20200/actuator/health
curl -sS http://127.0.0.1:20200/v3/api-docs \
| grep -E '/api/event-history/jt808/locations|/api/event-history/telemetry/fields'
| grep -E '/api/event-history/jt808/locations|/api/event-history/gb32960/snapshots|/api/event-history/telemetry/fields'
```
预期:健康检查为 `UP`OpenAPI 中包含这两个 TDengine 查询接口。
预期:健康检查为 `UP`OpenAPI 中包含 JT808 TDengine 分页查询接口和 GB32960 snapshot 接口。`/api/event-history/telemetry/fields` 会存在,但只有在 `TDENGINE_TELEMETRY_FIELDS_ENABLED=true` 后才会持续写入新字段数据
## 本机 launchctl 部署
@@ -142,7 +149,12 @@ Swagger
- `vehicle.event.jt808.v1`
- `vehicle.raw.jt808.v1`
使用 Kafka CLI 或管理工具检查 topic 是否存在,并确认 `vehicle-history` consumer group 在测试流量后没有持续堆积。
使用 Kafka CLI 或管理工具检查 topic 是否存在,并确认 history consumer group 在测试流量后没有持续堆积。默认 `KAFKA_GROUP_HISTORY=vehicle-history` 时,实际 group 会拆成:
- `vehicle-history-gb32960-event`
- `vehicle-history-gb32960-raw`
- `vehicle-history-jt808-event`
- `vehicle-history-jt808-raw`
## JT808 实时转发验收
@@ -162,15 +174,27 @@ curl -sS 'http://127.0.0.1:20200/api/event-history/jt808/locations?phone=<phone>
预期:响应包含 `items`,并且每条记录包含 `eventTime``phone``longitude``latitude``speedKmh``rawUri``metadataJson`
## GB32960 Snapshot / 字段投影验收
默认高吞吐模式下GB32960 全字段查询不依赖 telemetry_fields 宽表。history 先查 TDengine `raw_frames`,再按 `rawUri` 读取共享 archive 中的原始 `.bin` 并即时解析:
```bash
curl -sS 'http://127.0.0.1:20200/api/event-history/gb32960/snapshots?vin=<vin>&dateFrom=2026-06-29T00:00:00%2B08:00&dateTo=2026-06-29T23:59:59%2B08:00&limit=10'
curl -sS 'http://127.0.0.1:20200/api/event-history/gb32960/snapshots/fields?vin=<vin>&fields=VEHICLE.speedKmh,VEHICLE.totalMileageKm,POSITION_V2016.longitude,POSITION_V2016.latitude&dateFrom=2026-06-29T00:00:00%2B08:00&dateTo=2026-06-29T23:59:59%2B08:00&limit=10'
```
预期snapshot 返回 `sourceFrames.rawArchiveUri` 和解析后的 `blocks`;字段投影返回所选字段。新增协议字段后,只要解析器和字典补齐,就可以基于历史 raw 重新查询。
## Telemetry Field 查询验收
查询 GB32960 字段历史:
查询 GB32960 字段历史。该能力需要 `TDENGINE_TELEMETRY_FIELDS_ENABLED=true` 并确认压测后无持续 lag
```bash
curl -sS 'http://127.0.0.1:20200/api/event-history/telemetry/fields?protocol=GB32960&vin=<vin>&fieldKey=<field-key>&dateFrom=2026-06-29T00:00:00%2B08:00&dateTo=2026-06-29T23:59:59%2B08:00&limit=10'
```
查询 JT808 字段历史。没有 VIN 映射时,优先使用 `phone`
查询 JT808 字段历史。没有 VIN 映射时,优先使用 `phone`。该能力同样需要 `TDENGINE_TELEMETRY_FIELDS_ENABLED=true`
```bash
curl -sS 'http://127.0.0.1:20200/api/event-history/telemetry/fields?protocol=JT808&phone=<phone>&fieldKey=location.speed_kmh&dateFrom=2026-06-29T00:00:00%2B08:00&dateTo=2026-06-29T23:59:59%2B08:00&limit=10'
@@ -183,16 +207,18 @@ curl -sS 'http://127.0.0.1:20200/api/event-history/telemetry/fields?protocol=JT8
使用 TDengine CLI 或 JDBC 客户端检查超级表和子表是否创建:
```sql
USE vehicle_history;
USE vehicle_ts;
SHOW STABLES;
SELECT COUNT(*) FROM raw_frames;
SELECT COUNT(*) FROM vehicle_locations;
-- 仅在 TDENGINE_TELEMETRY_FIELDS_ENABLED=true 时检查:
SELECT COUNT(*) FROM telemetry_fields;
```
预期:
- `raw_frames``vehicle_locations``telemetry_fields` 存在。
- `raw_frames``vehicle_locations` 存在并持续增长
- `telemetry_fields` 表结构会创建;默认高吞吐模式不会持续增长,除非显式开启 `TDENGINE_TELEMETRY_FIELDS_ENABLED=true`
- 有实时流量后,计数持续增加。
## 失败语义
@@ -217,7 +243,7 @@ JT808 真实转发链路已验证:
- `vehicle.raw.jt808.v1``vehicle.event.jt808.v1` 被 history 消费。
- `raw_frames``protocol='JT808'` 的真实行数已超过 `6000`
- `vehicle_locations``protocol='JT808'` 的位置行数已超过 `1900`
- `telemetry_fields``protocol='JT808'` 的字段行数超过 `15000`
- 在旧的字段宽表开启模式下,`telemetry_fields``protocol='JT808'` 的字段行数超过 `15000`;当前高吞吐默认不要求该表持续增长
- 最新样例包含终端号 `13079963310`、消息 ID `512``archive://2026/06/29/JT808/...` 原始帧引用。
## JT808 本机 smoke / 轻压测工具
@@ -250,6 +276,7 @@ python3 tools/jt808_e2e_smoke.py \
USE vehicle_ts;
SELECT COUNT(*) FROM raw_frames WHERE protocol = 'JT808';
SELECT COUNT(*) FROM vehicle_locations WHERE protocol = 'JT808';
-- 仅在 TDENGINE_TELEMETRY_FIELDS_ENABLED=true 时复查:
SELECT COUNT(*) FROM telemetry_fields WHERE protocol = 'JT808';
SELECT event_time, vehicle_key, phone, message_id, raw_uri
FROM raw_frames
@@ -273,7 +300,7 @@ GB32960 链路已用合成实时帧验证:
- TCP `32960` 返回 GB32960 `2323` ACK。
- `raw_frames` 中测试 VIN `LTEST202606290001` 已有 `2` 条 raw 记录。
- `telemetry_fields` 中测试 VIN `LTEST202606290001` `34` 条字段记录。
- 在旧的字段宽表开启模式下,`telemetry_fields` 中测试 VIN `LTEST202606290001` `34` 条字段记录;当前默认通过 GB32960 snapshot/fields 即时解析 raw不要求该表增长
- latest raw 包含 `archive://2026/06/29/GB32960/LTEST202606290001/...`
- snapshots API 可查到 `speedKmh=62.4``totalMileageKm=223456.7``longitude=116.397128``latitude=39.916527`
@@ -283,6 +310,7 @@ GB32960 链路已用合成实时帧验证:
USE vehicle_ts;
SELECT COUNT(*) FROM raw_frames
WHERE protocol = 'GB32960' AND vin = 'LTEST202606290001';
-- 仅在 TDENGINE_TELEMETRY_FIELDS_ENABLED=true 时复查:
SELECT COUNT(*) FROM telemetry_fields
WHERE protocol = 'GB32960' AND vin = 'LTEST202606290001';
SELECT event_time, vin, raw_uri, frame_id
@@ -292,7 +320,7 @@ SELECT event_time, vin, raw_uri, frame_id
LIMIT 5;
```
也可以直接运行仓库 smoke 工具验证 TCP `32960`history records、TDengine 字段、TDengine `raw_frames` 和 raw archive
也可以直接运行仓库 smoke 工具验证 TCP `32960`GB32960 snapshot/fields、TDengine `raw_frames` 和 raw archive
```bash
export TDENGINE_REST_URL='http://<tdengine-host>:6041/rest/sql/vehicle_ts'
@@ -306,7 +334,7 @@ python3 tools/gb32960_e2e_smoke.py \
--tdengine-password "$TDENGINE_PASSWORD"
```
预期输出包含 `records >= 1``fieldCounts` 中关键字段均大于 0、`tdengineRawFrames` 等于本次可见唯一 `rawUri` 数量、`archiveChecked >= 1`
预期输出包含 `records >= 1``fieldCounts` 中关键字段均大于 0、`tdengineRawFrames` 等于本次可见唯一 `rawUri` 数量、`archiveChecked >= 1`这里的 `records` 字段表示 snapshot 数量,用于兼容早期脚本输出名。
复查 API