lingniu-dev 0e6f120ca9 feat(gb32960): introduce parser profile registry and rule-based vendor selector
Adds a per-context routing layer for InfoBlock parsers, so different
peers can be routed to different parser sets (e.g. standard GB/T 32960
vs. a vendor extension that adds blocks in the 0x30~0x7F reserved range).

New types in protocol-gb32960:
- Gb32960ParserContext (record): version + vin + platformAccount tuple
- codec/profile/VendorExtensionCatalog: name -> list of vendor parsers
- codec/profile/Gb32960ProfileRegistry: name -> InfoBlockParserRegistry,
  with a default registry built from the standard parsers and one extra
  registry per enabled vendor extension (default + vendor parsers)
- codec/profile/VendorExtensionSelector: interface returning the matching
  extension name (or null) for a given context
- codec/profile/RuleBasedVendorExtensionSelector: top-down first-match
  scan over Gb32960Properties.vendorExtensions with a (account,vin)
  cache keyed on case-insensitive normalized form

Gb32960Properties gains a `vendorExtensions` list with per-entry
`name` + `match` (platformAccounts / vins / vinPrefixes). All matching
fields are OR'd within an entry; entries are scanned top-down with
first-match-wins as documented.

Gb32960BodyParser keeps its legacy single-registry constructor for
back-compat (used by existing tests) and adds a new constructor that
takes the profile registry + selector. The parse loop now lives under
parse(Gb32960ParserContext, ByteBuffer); the legacy parse(version,body)
delegates to it with a minimal context (selector returns null -> default).

This commit only introduces the framework. Vendor parsers, autoconfig
wiring, and decoder/handler context plumbing land in follow-ups.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:37:15 +08:00

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/sP99 < 50 ms
  • 可观测、可回放、可灰度:统一 traceId、Envelope、幂等键、DLQ、原始报文冷存

技术栈

类别 选型
语言 Java 25
框架 Spring Boot 3.4.x
网络 Netty 4.1
并发 Disruptor 4 + 虚拟线程 + StructuredTaskScope
消息队列 Kafkavin 分区,保证单车有序)
线上消息格式 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

核心原则

  1. 本服务不写业务库:历史、行程、在线检测、里程统计全部由 Kafka 下游消费者实现
  2. 协议即插拔:每个 protocol-* / inbound-* 都可独立开关(lingniu.ingest.<name>.enabled
  3. 顺序保证:同一 VIN 严格有序Disruptor hash + Kafka 分区 key
  4. 幂等消费Envelope 带 eventId,下游去重
  5. 原始可回放vehicle.raw.archive topic + 对象存储
Description
No description provided
Readme 129 MiB
Languages
Java 81.7%
Go 12.3%
Python 5.9%