内容提要
文章介绍基于芋道微服务二开的JT/T 808车辆监控平台:先厘清808定位、1078视频、809平台对接三项国标,再说明终端、Netty网关、业务服务、应用、用户五层架构。核心设计是网关与业务分进程,仅通过RocketMQ信封通信;实时数据写入Redis,历史轨迹按月分区存入PostgreSQL。并总结惊群、MQ阻塞、坐标混用三个常见问题。
延伸解读
网关与业务分进程:规模化的关键取舍
文章强调将Netty网关与业务服务拆分为独立进程,仅通过RocketMQ信封通信。这一设计源于三个现实差异:协议与业务变化频率不同、资源特征不同(IO密集 vs CPU/DB密集)、扩容粒度不同。合并部署时,业务发版重启会导致数千TCP连接断开,终端批量重连形成惊群,甚至打挂网关。分进程后,业务可独立发版,连接层稳定,平台从百台车扩展到万台车只需增加网关实例,代码结构无需改动。
数据分层:Redis快照与PostgreSQL月分区
针对车联网数据“最新值万金、历史是档案”的特点,平台采用冷热分线存储。实时线用Redis保存终端会话、鉴权码和最后位置快照,监控页面通过WebSocket增量推送,避免数据库轮询。历史线用PostgreSQL,轨迹和报警表按月分区,每月自动预建下月分区,查询只扫当月,超期分区整月detach归档,比批量DELETE更高效且不产生表膨胀。写入也分快慢两轨:低频档案走MyBatis-Plus,高频轨迹走JdbcTemplate直写。
三个典型坑:惊群、MQ阻塞与坐标混用
文章总结了实战中踩过的三个坑。惊群:网关与业务同进程时,发版重启引发终端批量重连,恶性循环打挂服务,解法是连接与业务分进程。MQ阻塞:早期IO线程同步调业务,慢SQL反压导致读事件延迟、终端断线,此后立规“IO线程零阻塞,一切慢操作过MQ”。坐标混用:前端混用WGS-84和GCJ-02,同一车辆位置差出几百米,最终强制服务端只存只推WGS-84,渲染端负责最后一跳转换。这些纪律保障了平台稳定。
Q&A
JT/T 808、1078、809 这三个国标分别负责什么?
JT/T 808 是定位与控制协议,规定车载终端与监控平台之间的通信;JT/T 1078 是视频协议,负责音视频传输;JT/T 809 是平台对平台协议,用于向上级监管平台转发数据。
为什么车联网平台要基于芋道微服务二开而不是从零写?
因为车联网平台 80% 的代码是后台管理标配功能(组织权限、租户隔离、日志等),从零写会浪费大量时间造轮子;基于芋道二开可以复用这些脚手架,让团队集中精力在协议、链路和性能等核心部分。
平台的五层架构具体是哪五层?每层做什么?
五层从下到上为:终端层(真车终端和模拟器)、接入层(三个独立 Netty 网关,负责协议解码并投递 MQ)、服务层(jt-server 处理业务,消费 MQ 信封)、应用层(Web 管理端、小程序、开放 API)、用户层(六类角色)。
为什么网关必须独立成进程,不能和业务逻辑放在一起?
因为协议侧和业务侧变化频率不同、资源特征不同(网关 IO 密集,业务 CPU/DB 密集)、扩容粒度不同。合在一起会导致改业务重启时大量 TCP 连接断开,引发惊群,且资源互相争抢,难以定位问题。
实时数据和历史轨迹分别存储在哪里?为什么这样设计?
实时数据(终端会话、最后位置快照)存 Redis,因为 99% 的实时查询只关心车辆当前位置,Redis 快照加 WebSocket 推送可避免数据库压力;历史轨迹存 PostgreSQL 并按月分区,因为历史数据量大且需长期留存,分区便于查询和归档。
文章提到了哪三个常见的坑?如何解决?
一是惊群:网关和业务同进程,发版重启导致大量终端重连打挂服务,解法是连接与业务分进程;二是把 MQ 当可选项:IO 线程同步调业务导致阻塞,解法是 IO 线程零阻塞,慢操作过 MQ;三是坐标混用:前端使用不同坐标系导致位置偏差,解法是服务端只存 WGS-84,渲染端负责转换。