957a86d5811a2da7336d55606bdda35a769a0e61
Adds 6 vendor parsers under codec/parser/vendor/guangdong/ implementing the Guangdong "燃料电池汽车数据接入技术规范 v1.0" extension typeCodes that the city's data ingestion platform sends inside V2016 frames: 0x30 GdFcStackBlockParser §7.2.3.4 表 13/14 fuel-cell stack 0x31 GdFcAuxiliaryBlockParser §7.2.3.5 表 15/16 auxiliary system 0x32 GdFcDcDcBlockParser §7.2.3.6 表 17 DC/DC 0x33 GdFcAirConditionerBlockParser §7.2.3.7 表 18 air conditioner 0x34 GdFcVehicleInfoBlockParser §7.2.3.8 表 19 vehicle info 0x80 GdFcDemoExtensionBlockParser §7.2.3.14 表 27 demo data extension Each parser uses ProtocolVersion.V2016 + its respective typeCode and is strictly Guangdong-spec layout, not the GB/T 32960.3-2025 fuel-cell stack layout (the two share typeCode 0x30 but have different field orders and extra cell-voltage statistics in the Guangdong variant). Field model in InfoBlock.java gains: - GdFcStack(stackCount, stacks: Stack(workState, waterTempC, h2InletPressureKpa, airInletPressureKpa, airInletTempC, max/min/avg cell voltage ids and values, cellCount, frameCellStart, frameCellCount, frameCellVoltagesV)) - GdFcAuxiliary(subSystemCount, subsystems: Subsystem with air compressor, hydrogen pump, water pump, PTC, low-voltage battery) - GdFcDcDc, GdFcAirConditioner, GdFcVehicleInfo, GdFcDemoExtension InfoBlockType enum gains the matching GD_FC_* constants. Tests: - GdFcParserTest covers the 4 fixed-length parsers (0x32/0x33/0x34/0x80) with hand-crafted bytes asserting field-by-field decoded values. - 0x30/0x31 are variable-length and will be exercised end-to-end via the body parser integration test in a follow-up. Spec doc: adds reference/广东燃料电池汽车示范应用城市群综合监管平台-...pdf (v1.0.220822) used as the source of truth for these parsers. These parsers exist as classes only; no Spring beans are wired yet. Wiring + decoder context plumbing land in the next commit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
lingniu-vehicle-ingest
羚牛车辆数据接入平台 v2
设计目标
- 协议接入统一抽象:GB/T 32960、JT/T 808、JT/T 1078、JSATL12、MQTT、信达 Push 全部变成可插拔 Inbound Adapter
- 原子能力化:每个协议一个独立 Maven 模块 + 独立 AutoConfiguration + 独立配置开关
- 业务 / 实时彻底解耦:本服务只负责 收 → 解析 → 校验 → 规整 → 投递 Kafka,不碰业务库
- 高并发低延迟:Netty + Disruptor + Java 25 虚拟线程;目标单节点 ≥ 5 万 msg/s,P99 < 50 ms
- 可观测、可回放、可灰度:统一 traceId、Envelope、幂等键、DLQ、原始报文冷存
技术栈
| 类别 | 选型 |
|---|---|
| 语言 | Java 25 |
| 框架 | Spring Boot 3.4.x |
| 网络 | Netty 4.1 |
| 并发 | Disruptor 4 + 虚拟线程 + StructuredTaskScope |
| 消息队列 | Kafka(vin 分区,保证单车有序) |
| 线上消息格式 | Protobuf,调试走 JSON |
| MQTT 客户端 | HiveMQ MQTT Client |
| 会话缓存 | Caffeine + Redis 兜底 |
| 熔断/限流 | Resilience4j 2 |
| 可观测 | Micrometer + Prometheus + OpenTelemetry |
| 冷存 | S3 / OSS / 本地 |
| 构建 | Maven + Spotless + ArchUnit |
模块划分
lingniu-vehicle-ingest/
├── bom/ 依赖版本统一
├── ingest-api/ SPI + sealed 领域事件 + 注解
├── ingest-codec-common/ 公共编解码工具(BCD/CRC/BCC/bit utils)
├── ingest-core/ Pipeline / Dispatcher / Disruptor / Session 桥
├── session-core/ 设备会话 + 鉴权 + Token
├── observability/ metrics / tracing / health
├── sink-mq/ Kafka producer + Protobuf Envelope
├── sink-archive/ 原始报文冷存
├── protocol-gb32960/ GB/T 32960
├── protocol-jt808/ JT/T 808
├── protocol-jt1078/ JT/T 1078
├── protocol-jsatl12/ 苏标主动安全报警附件
├── inbound-mqtt/ MQTT 接入(宇通等)
├── inbound-xinda-push/ 信达 Push 接入(重写)
├── command-gateway/ HTTP → 设备下行命令
└── bootstrap-all/ 一体化启动
快速开始
# 要求:JDK 25, Maven 3.9+
mvn -v
mvn clean install -DskipTests
cd bootstrap-all && mvn spring-boot:run
迁移说明
本项目是 lingniu-vehicle-data-reception 的 v2 重构,采用 strangler fig 渐进式迁移,旧项目保留只读参考。迁移路径与决策参见 ../REFRACTOR_PLAN.md。
核心原则
- 本服务不写业务库:历史、行程、在线检测、里程统计全部由 Kafka 下游消费者实现
- 协议即插拔:每个
protocol-*/inbound-*都可独立开关(lingniu.ingest.<name>.enabled) - 顺序保证:同一 VIN 严格有序(Disruptor hash + Kafka 分区 key)
- 幂等消费:Envelope 带
eventId,下游去重 - 原始可回放:
vehicle.raw.archivetopic + 对象存储
Description
Languages
Java
81.7%
Go
12.3%
Python
5.9%