车联网开发入门:Docker 搭建 EMQX + TDengine,跑通第一条车联网消息

车联网开发入门:Docker 搭建 EMQX + TDengine,跑通第一条车联网消息 大概花了两个小时从零把车联网最核心的两个组件——MQTT Broker 和时序数据库——在本地跑起来了。一、为什么要学 MQTT之前做后端接口通信基本都是 HTTP。但车联网场景下HTTP 有几个很明显的短板。HTTP 的问题在哪平时写 Spring Boot 接口客户端发请求 → 服务端响应没问题。但如果是一辆车每秒上报一次 GPS用 HTTP 的话每次都要 TCP 三次握手一万辆车就是每秒一万次握手连接开销大到不划算。还有一个更直观的问题服务端想主动给车发指令怎么办比如远程开空调。HTTP 是「请求-响应」模型服务端没能力主动推送只能靠车机轮询——隔几秒问一次「有没有新指令」大部分时候都是空转耗电耗流量。地库、隧道这种弱网环境下HTTP header 大几百字节丢包重传成本也高。MQTT 怎么解决的MQTT 是一种发布/订阅模式的轻量级消息协议设计之初就是给物联网用的。车辆发布者──发布 Topic: vehicle/001/data ──→ EMQX Broker ←──订阅 Topic: vehicle//data ── Java 后端核心区别维度HTTPMQTT通信模型请求-响应发布-订阅连接短连接用完即断长连接一直保持消息方向只能客户端主动双向收发消息头几百字节最小 2 字节弱网频繁重连自动重连 离线缓存QoS 三级——这个很重要QoS 是 MQTT 最核心的设计QoS 0发一次丢了不管。适合 GPS 上报丢了就丢了下一秒还有新的。QoS 1至少送到一次可能重复。适合状态上报收到就行多一次没关系。QoS 2精确送达一次绝不重复。适合远程控车指令——重复执行会出事故。二、EMQX 和 MQTT 是什么关系刚开始很容易搞混其实很简单MQTT 是协议标准就像 SQLEMQX 是具体实现就像 MySQL。学了 MQTT 概念得装个 Broker 才能真正用起来。市面上几个主流的 MQTT BrokerMosquitto很轻量适合嵌入式和测试功能简单EMQX分布式、高性能支持 MQTT 5.0、WebSocket、规则引擎车联网项目用得多HiveMQ商业付费为主NanoMQ也是 EMQ 团队的跑在边缘端比如车机本身选 EMQX 主要是因为它自带 Dashboard对新手友好。不装任何客户端浏览器打开就能看到连接数、消息量、Topic 列表。查资料的时候发现 B 站上 EMQX 的教程不多一开始也担心是不是过时了。后来看了下 GitHub 有 14k Star2025 年 11 月刚发 6.0 大版本其实是因为这种基础设施类的技术主流学习方式就是看官方文档和动手实践不像前端框架那样视频教程满天飞。三、为什么要学 TDengine车联网数据有个特点每条记录都带时间戳写入多、更新少、几乎不删查询也是按时间范围。这种数据类型叫「时序数据」。MySQL 存时序数据很吃力行存 BTree 索引写入几千条/秒到头了百万辆车每秒一条MySQL 根本写不动磁盘占用大基本不压缩按时间范围查大数据量时很慢TDengine 专门为这种场景设计列存按时间段压缩写入百万条/秒压缩比 10:1省磁盘内置降采样、插值、窗口函数聚合查询很快支持 SQL 和 JDBCJava 开发直接用四、动手搭建环境官方文档是最好的教程我按照 Quick Start 一步步来的。前置Docker先确认 Docker 能用docker--version dockerps国内网络要配镜像加速编辑C:\Users\你的用户名\.docker\daemon.json{registry-mirrors:[https://docker.1panel.live,https://dockerproxy.net,https://hub-mirror.c.163.com]}改完重启 Docker Desktop。Step 1装 EMQX参考https://www.emqx.io/docs/zh/latest/getting-started/docker run-d--name emqx-p 1883:1883-p 18083:18083 emqx/emqx:latest1883MQTT 协议端口设备连这个18083Dashboard 管理界面浏览器打开 http://localhost:18083账号 admin密码 public登录后就能看到管理后台。Step 2装 TDengine参考https://docs.tdengine.com/get-started/docker run-d--name tdengine-p 6030:6030-p 6041:6041-p 6060:6060 tdengine/tdengine:latest6030客户端连接端口Java JDBC 用这个6041REST API 端口taosAdapter6060Web 控制台taosExplorer3.x 版本新增浏览器打开 http://localhost:6060账号 root密码 taosdata。到这一步两个核心组件就都在 Docker 里跑起来了。Step 3用 MQTTX 发第一条消息MQTTX 是官方出的 MQTT 桌面调试工具下载地址https://mqttx.app/安装后新建连接Host:localhostPort:1883连接成功后会显示绿色的 Connected。然后发一条消息Topic:vehicle/001/dataQoS:1Payload:{vin:VIN001,speed:60,battery:85,lat:30.5928,lng:114.3055}点击发送。去 EMQX Dashboard 的 Monitoring 页面能看到消息计数在涨——说明消息成功经过 Broker 了。这时候感觉挺奇妙的虽然是模拟的但这就是真实车联网场景的最小原型。Step 4TDengine 建表并查询打开 TDengine 控制台 http://localhost:6060在 Explorer 的 SQL 编辑器里逐条执行。4.1 创建数据库CREATEDATABASEvehicle KEEP365d;vehicle数据库名后面所有表都建在这个库下面KEEP 365d数据保留 365 天超过自动删除。车联网数据量大必须设过期策略不然磁盘很快就满4.2 创建超级表CREATESTABLE vehicle.t_vehicle_data(tsTIMESTAMP,speedINT,batteryINT,latDOUBLE,lngDOUBLE)TAGS(vinNCHAR(20));这条值得拆开说。超级表STable是 TDengine 和 MySQL 最大的不同。所有车的数据结构都一样——时间、速度、电量、经纬度如果 100 万辆车建 100 万张表管理成本太高。超级表就是「模板表」括号内ts、speed、battery、lat、lng数据列每辆车都存这些字段TAGS (vin NCHAR(20))标签列用来区分不同车辆。这里用 VIN 码车架号做标签每辆车唯一类比一下的话超级表像 Java 里的抽象类子表是具体实例。建好模板之后每辆车只需要一行CREATE TABLE ... USING就能有自己的子表。4.3 创建子表CREATETABLEvehicle.v_vin001USINGvehicle.t_vehicle_data TAGS(VIN001);v_vin001子表名命名规则是v_ VIN 码一眼就知道是哪辆车USING vehicle.t_vehicle_data继承超级表的列定义TAGS (VIN001)给这辆车的标签赋值建完之后这辆车就有了ts、speed、battery、lat、lng五个数据列标签标记为VIN001。以后要查这辆车的所有数据直接SELECT * FROM vehicle.v_vin001就行。4.4 插入数据INSERTINTOvehicle.v_vin001VALUES(NOW,60,85,30.5928,114.3055);NOW当前时间戳TDengine 自动填充后面依次是速度 60、电量 85%、纬度 30.5928、经度 114.3055武汉坐标不用写 vin 字段因为标签已经在建表时固定了4.5 查询验证SELECT*FROMvehicle.v_vin001;能看到一条记录就说明整条链路通了。 超级表的真正威力后面才会体现当你有 100 个子表100 辆车可以对超级表直接SELECT AVG(speed) FROM vehicle.t_vehicle_data WHERE ts ...一次查询覆盖所有车不用UNION ALL。小结一下环境Docker ├── EMQX ← MQTT 消息中枢 → http://localhost:18083 └── TDengine ← 时序数据仓库 → http://localhost:6060五、踩坑记录1. Docker 拉镜像超时配镜像加速后重启 Docker Desktop 解决。2. 装了之后 Docker 一堆容器自启动之前装的 RocketMQ、Redis、MySQL 每次开机都起来占用资源。用docker stop xxx停掉docker rm xxx删掉就干净了。Docker Desktop 设置里还可以关掉开机自启。3. EMQX 和 MQTT 混淆一开始以为 EMQX 就是 MQTT后来才理清MQTT 是协议EMQX 是实现。就像 HTTP 和 Nginx 的关系。六、学完的感受之前对 MQTT 的理解只停留在「物联网用的协议」时序数据库也只是听说过。亲手搭一遍之后感觉完全不一样了Topic 的设计、QoS 三级、发布订阅模型写代码的时候知道选什么了TDengine 的超级表结构建过表之后比看文档直观多了从 MQTTX → EMQX → 浏览器 Dashboard亲眼看到消息流过的路径下一篇准备用 Java 代码取代 MQTTXSpring Boot 集成 Eclipse Paho把接收到的消息直接写进 TDengine。车联网学习笔记持续更新。