# 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 | | 会话缓存 | Redis 生产索引 + Caffeine 内存降级 | | 熔断/限流 | Resilience4j 2 | | 可观测 | Micrometer + Prometheus + OpenTelemetry | | 冷存 | S3 / OSS / 本地 | | 构建 | Maven + Spotless + ArchUnit | ## 模块划分 ``` lingniu-vehicle-ingest/ ├── modules/ │ ├── core/ │ │ ├── ingest-api/ SPI + sealed 领域事件 + 注解 │ │ ├── ingest-codec-common/ 公共编解码工具(BCD/CRC/BCC/bit utils) │ │ ├── ingest-core/ Pipeline / Dispatcher / Disruptor / Session 桥 │ │ ├── session-core/ 设备会话 + 鉴权 + Token + Redis/Memory SessionStore │ │ ├── vehicle-identity/ 跨协议车辆身份解析 + 外部标识绑定(memory/file) │ │ └── observability/ metrics / tracing / health │ ├── protocols/ │ │ ├── protocol-gb32960/ GB/T 32960 │ │ ├── protocol-jt808/ JT/T 808(统一身份映射 + 事件 metadata 内部 VIN + 注册/鉴权/心跳/注销/位置/批量位置/参数/属性/媒体/透传/未知上行和坏帧兜底/断链清理会话/下行分包) │ │ ├── protocol-jt1078/ JT/T 1078(808 信令按需桥接 + 常用下行信令编码 + TCP/UDP RTP 媒体流分段归档 + 事件 metadata 内部 VIN + 坏 RTP 统一 RawArchive/Passthrough + 归档失败兜底 + SIM 身份映射) │ │ └── protocol-jsatl12/ 苏标主动安全报警附件(真实 DataPacket 分帧 + 附件流归档 + T1210 文件清单身份继承 + 9212 补传应答 + MediaMeta 引用事件 + 坏帧/坏信令/归档失败兜底) │ ├── inbound/ │ │ ├── inbound-mqtt/ MQTT 接入(endpoint 生命周期 + profile 注册扩展 + 统一身份映射 + PEM 双向 TLS + 未知 profile/解析失败/profile异常/连接订阅失败兜底 + 统一 UNKNOWN 身份 metadata) │ │ └── inbound-xinda-push/ 信达 Push 接入(统一身份映射 + 事件 metadata 内部 VIN + 未知业务 cmd/解析失败/启动配置失败/业务处理异常兜底) │ ├── sinks/ │ │ ├── sink-mq/ Kafka producer + Protobuf Envelope │ │ ├── sink-archive/ 原始报文冷存 │ │ └── event-file-store/ Parquet + DuckDB 文件型明细库 │ ├── services/ │ │ ├── event-history-service/ Kafka 全字段事件消费 + 历史查询/导出 │ │ ├── vehicle-state-service/ Kafka 全字段事件消费 + Redis 热状态查询 │ │ └── vehicle-stat-service/ Kafka 全字段事件消费 + 可配置日统计 │ └── apps/ │ ├── command-gateway/ HTTP → 设备下行命令(808 位置/参数/属性/控制/区域删除/报警确认 + 1078 音视频控制) │ ├── gb32960-ingest-app/ GB32960 TCP 接入 + Kafka 投递 │ ├── vehicle-history-app/ 历史查询 + 原始归档索引消费 │ └── vehicle-analytics-app/ 车辆状态/日统计消费 ├── docs/ 架构文档、模块图、实施计划 └── reference/ 参考资料 ``` ## 快速开始 ```bash # 要求:JDK 25, Maven 3.9+ mvn -v mvn clean install -DskipTests mvn -pl :gb32960-ingest-app -am spring-boot:run ``` ## 迁移说明 本项目是 `lingniu-vehicle-data-reception` 的 v2 重构,采用 strangler fig 渐进式迁移,旧项目保留只读参考。迁移路径与决策参见 `../REFRACTOR_PLAN.md`。 ## 架构文档 - 目标架构:`docs/target-architecture.md` - 内部字段模型:`docs/vehicle-telemetry-internal-fields.md` - 模块与数据流:`docs/module-data-flow.html` ## 核心原则 1. **本服务不写业务库**:历史、行程、在线检测、里程统计全部由 Kafka 下游消费者实现 2. **协议即插拔**:每个 `protocol-*` / `inbound-*` 都可独立开关(`lingniu.ingest..enabled`) 3. **顺序保证**:同一 VIN 严格有序(Disruptor hash + Kafka 分区 key) 4. **幂等消费**:Envelope 带 `eventId`,下游去重 5. **原始可回放**:Dispatcher 会先发布 `RawArchive`,并把同一份 `rawArchiveKey/rawArchiveUri` 追加到业务事件 metadata;下游明细库、Kafka Envelope 和导出都使用 `archive://...` 逻辑 URI 追溯原始 bytes,实际文件由 `sink-archive`/`ArchiveStore` 管理;`event-file-store` 只额外保存 RawArchive 查询索引,不嵌入原始 bytes