
最近在给一个设备数据采集项目搭建消息通道选型的时候在几个MQTT broker 之间来回对比了一圈最后定下来用 EMQX 做 MQTT 服务器。这篇文章就是我从零开始把 EMQX 部署起来、跑通客户端连接、处理常见坑的完整记录。标题里写的mtqq其实是 MQTT 的笔误不影响理解我们就按 MQTT 来讲。如果你现在正打算自建一套 MQTT 服务器或者已经在用 Mosquitto、RabbitMQ 但觉得扩展性和管理界面不够顺手那这篇文章应该能帮你省不少时间。我会从协议基础讲起到 Docker 部署 EMQX、Dashboard 配置、客户端测试再到排障实录一步一步把整个链路说透。无论你是刚接触物联网的新手还是已经在做设备接入的工程师都能照着操作。1. 选型之前MQTT 服务器到底在解决什么问题1.1 MQTT 协议的核心机制先说清楚 MQTT 是个什么东西。很多刚入门的同学容易把 MQTT 和 HTTP 放一起比较但这两个东西解决的问题完全不一样。HTTP 是典型的请求-响应模型客户端发起请求服务器返回结果连接用完就断。这在网页浏览场景没问题但放到物联网场景就很尴尬一个温湿度传感器每隔几秒上报一次数据服务器要主动向设备下发一条控制指令这两件事用 HTTP 来做轮询成本高、实时性差、连接开销大。MQTT 是发布订阅模型中间站着一个 Broker消息服务器。设备A 发布消息到某个主题设备B 订阅了同一个主题就能收到这条消息。生产者和消费者完全解耦不需要知道对方存在也不用约定 IP 和端口。这个模型和微信群的逻辑很像你在群里发一条消息群成员都能看到但发消息的人不需要单独给每个人发一遍。MQTT 在设计上针对低带宽、高延迟、网络不稳定的物联网环境做了大量优化比如 QoS 机制、保留消息、遗嘱消息、心跳保活等。QoS 0/1/2 对应不同的消息投递保证等级网络断开时可以用遗嘱消息通知其他设备这台设备掉线了这些特性都是 HTTP 很难自然支持的。1.2 为什么最终选了 EMQX 而不是其他 Broker市面上的 MQTT Broker 并不少开源的有 Mosquitto、VerneMQ、HiveMQ社区版商业的也有 EMQX 企业版等。我自己的踩坑经历是从 Mosquitto 开始的。Mosquitto 轻量、资源占用小单机跑几百上千个连接也没问题但到了真正做项目的时候会发现几个痛点。第一是管理界面。Mosquitto 默认没有 Web Dashboard要看连接数、订阅情况全靠命令行排查问题的时候效率很低。第二是规则处理能力设备上报的数据要做格式转换、字段提取、条件过滤Mosquitto 自己干不了得单独写一个后端服务去订阅、处理、再转发链路变长出故障的概率也上去了。第三是集群和高可用Mosquitto 虽然从 2.0 开始也支持集群但配置复杂社区资料相对少。EMQX 这几个短板正好都补上了。它自带一个功能完整的 Web Dashboard连接数、消息速率、主题列表、订阅关系一目了然。内置了规则引擎数据从设备端进来之后可以直接在 EMQX 里做过滤、重发布、桥接到数据库或 Kafka不用再额外搭业务逻辑。集群能力是从底层设计的扩展节点比较简单对生产环境友好。加上 EMQX 原生支持 MQTT 3.1/3.1.1/5.0 三个协议版本也支持 WebSocket、CoAP 等其他接入协议几乎把物联网接入侧的协议问题一次性解决了。2. 部署方案选择Docker 还是二进制包2.1 我为什么推荐用 Docker 部署 EMQXEMQX 官方提供了多种安装方式RPM/DEB 包安装、二进制 ZIP 包、Docker 镜像、Kubernetes Operator。如果你是在正式服务器上部署我最推荐的是 Docker 方式理由很简单环境隔离、依赖干净、迁移方便。之前我在一台 CentOS 7 上直接装 RPM 包装完之后发现它依赖的 Erlang 版本和系统里的其他程序冲突折腾了半天才搞定。用 Docker 就没有这个问题镜像里自带运行时环境宿主机只需要有一个能跑 Docker 的系统基本上不会出现在我机器上明明能跑这种尴尬事。另外Docker 容器可以随时删掉重建部署脚本也方便备份和版本管理这对后续维护非常友好。2.2 部署前需要确认的几件事EMQX 本身对硬件的要求不高跑测试的话 1 核 1G 内存就够用生产环境建议 2 核 4G 起步。磁盘占用主要是日志和消息持久化数据EMQX 默认不做消息存储它更像一个路由器而不是数据库所以磁盘压力不算大。操作系统方面Linux 是最常见的选择Windows 也能跑 Docker Desktop 或直接用安装包但生产环境建议还是用 Linux。部署前要把端口规划好。EMQX 默认监听这样几个端口端口用途1883MQTT over TCP 标准端口8883MQTT over TLS/SSL 加密端口8083MQTT over WebSocket 端口8084MQTT over WSSWebSocket TLS端口18083EMQX Dashboard 管理界面端口我习惯把 1883 和 18083 这两个端口作为最小可用集合先跑通再按需开放其他端口。注意 18083 是管理界面端口不应该暴露到公网否则会有被暴力破解的风险。2.3 版本选型5.x 还是 4.xEMQX 目前主推 5.x 系列我在部署时也选了最新的 5.x。5.x 相比 4.x 有几个重要变化Dashboard 完全重构了界面更现代化操作路径也变了配置方式从 HOCON 格式统一到 emqx.conf规则引擎的编写方式也有调整。如果你直接看网上搜到的一些老教程里面写的 4.x 配置方法在 5.x 上很可能对不上所以部署前先确认你用的版本再看对应文档。我的建议是新项目直接用 5.x别走回头路。4.x 虽然也还在维护但功能迭代基本围绕 5.x 展开没必要用老版本给自己挖坑。下面我的部署步骤也是基于 emqx/emqx:5.x 镜像写的。3. 实操一步步把 EMQX 跑起来3.1 安装并确认 Docker 环境如果你服务器上还没有 Docker先装 Docker。不同发行版安装方式不同以 Ubuntu 为例就是几条命令的事sudo apt update sudo apt install docker.io sudo systemctl enable --now docker如果是 CentOS用sudo yum install docker-ce会更接近官方源不过用发行版自带的 docker.io 或 docker 包也能跑起来。装完后用一个简单命令确认环境docker --version docker psdocker ps能正常输出列表哪怕为空说明 Docker 守护进程在运行。这一步经常有人卡住如果你发现执行docker ps报Cannot connect to the Docker daemon先检查 Docker 服务有没有启动sudo systemctl start docker然后再试一次。另外提一句国内服务器拉取 Docker Hub 镜像可能会比较慢可以给 Docker 配一个镜像加速器。这个属于基础操作具体配置方法可以在 Docker 官方文档里找到这里就不展开了。3.2 拉取镜像并启动容器确认 Docker 环境没问题后拉取 EMQX 镜像docker pull emqx/emqx:5.7.1版本号可以按需换成最新的 5.x如果只想拉最新版也可以不带版本号直接docker pull emqx/emqx但生产环境建议锁定具体版本方便管理和回溯。启动容器的命令如下sudo docker run -d --name emqx \ -p 1883:1883 \ -p 8083:8083 \ -p 8084:8084 \ -p 8883:8883 \ -p 18083:18083 \ emqx/emqx:5.7.1这条命令做的事情是以后台模式运行一个名为 emqx 的容器把宿主机的 1883、8083、8084、8883、18083 端口分别映射到容器内的对应端口镜像用我们刚拉下来的 5.7.1。-d参数让容器后台运行终端不会卡住。启动之后确认容器状态sudo docker ps如果看到STATUS是Up的 emqx 容器说明服务已经跑起来了。再用sudo docker logs emqx查看启动日志如果日志里出现类似EMQX 5.7.1 is running now!的信息基本就成了。3.3 验证 EMQX 服务是否正常启动容器后先在服务器本地验证两个端口。第一个是 MQTT 端口 1883看它是否在监听sudo netstat -tlnp | grep 1883第二个是 Dashboard 端口 18083。在浏览器里访问http://服务器IP:18083如果能看到 EMQX 的登录页面说明管理界面也正常。这里需要注意如果你是用云服务器域名或 IP 对应的安全组/防火墙规则里必须放行 1883 和 18083 端口否则浏览器访问会超时。很多同学第一步就卡在这个地方本地怎么测都通换到公网访问就失败十有八九是安全组没配白名单。3.4 用 Docker Compose 固化部署流程直接跑docker run适合验证但生产部署我更推荐用 Docker Compose。把启动参数固化到文件里以后服务器重启、换机器、升级版本都只要一条命令搞定。创建一个目录比如~/emqx-deploy然后在里面创建docker-compose.ymlversion: 3.8 services: emqx: image: emqx/emqx:5.7.1 container_name: emqx restart: always ports: - 1883:1883 - 8083:8083 - 8084:8084 - 8883:8883 - 18083:18083 volumes: - ./data:/opt/emqx/data - ./log:/opt/emqx/log启动命令docker compose up -drestart: always的作用是容器意外退出时自动拉起这对生产环境非常重要。volumes挂载是我特别强调的后面第 4 节细说。4. 基础配置认证、账号与 Dashboard4.1 Dashboard 初体验打开 Dashboard 登录页后默认账号是admin默认密码是public。5.x 版本在首次登录时会强制要求修改密码这个设计很合理毕竟admin/public属于公开的默认凭据不改成强密码就相当于裸奔。登录进去之后你会看到几个核心模块。Dashboard 首页展示连接数、消息流入流出速率、订阅数等实时指标这些都是排查问题时的第一手信息。在连接管理里可以查看当前所有客户端连接包括客户端的 Client ID、IP 地址、协议版本、保持连接时间等。在主题和订阅页面可以看到当前 Broker 上有哪些主题在流转、谁订阅了谁。我第一次用 EMQX 的时候最大感受是原来消息链路是可以看得这么清楚的。对比之前用 Mosquitto 靠命令行一条条查EMQX 确实省心太多。4.2 关闭匿名认证创建客户端账号EMQX 默认开启了匿名认证也就是任何客户端只要拿到 Broker 地址和端口不需要账号密码就能连接。这在局域网测试环境图省事可以但一旦暴露到公网任何人都能往你的主题里发消息甚至订阅你的数据风险极大。所以部署完第一件事我建议关闭匿名认证并创建正式的客户端账号。操作路径是 Dashboard 左侧菜单的访问控制 - 认证在认证设置里把启用匿名认证关掉然后添加一个新的认证数据源。EMQX 支持很多种认证方式最简单的是使用内置数据库直接在 Dashboard 里创建用户名和密码。创建完成后把所有客户端配置都改成使用这个账号连接同时把默认的 admin 密码换成高强度密码。这样即使 Broker 端口暴露在外攻击者也得先过认证这一关。4.3 数据持久化与日志EMQX 运行过程中会把一些状态数据、配置改动、日志写到容器内部的/opt/emqx/data和/opt/emqx/log目录。如果你没有挂载数据卷容器一旦被删除这些数据就全没了。我早期踩过这个坑。有一次调规则引擎配置调整了半天后来为了升级版本把容器删了重建结果所有配置回到初始状态相当于白干了。后来我学乖了部署时一定加上文件挂载让数据落在宿主机上。这样升级版本时只要把新容器挂载到同一个数据目录旧配置、旧数据都能保留基本做到无缝迁移。日志方面EMQX 默认的日志级别是 info会记录连接、认证、消息路由等关键事件。排查问题时可以先去/opt/emqx/log目录下看emqx.log很多连接失败、认证失败的根因都能在里面找到。如果磁盘空间紧张还要注意日志轮转策略避免日志文件无限增长把磁盘撑爆。5. 客户端连接测试验证你的 MQTT 链路5.1 用 MQTTX 做图形化测试部署完 EMQX下一步就是验证客户端能不能正常连接。MQTTX 是我最常用的客户端工具跨平台、界面直观、支持 MQTT 3.1.1 和 5.0非常适合做连接测试和数据收发验证。新建连接时填写这几个参数Broker 地址填部署 EMQX 的服务器 IP端口填 1883默认 TCPClient ID 可以随便填一个唯一的字符串比如mqttx-test-001。如果已经关闭了匿名认证还要在用户名/密码里填上之前创建的账号。配置完成后点击连接看到连接状态变成绿色说明 TCP 连接和认证都通过了。接着测试消息收发。在 MQTTX 里订阅一个主题比如test/topic然后在另一个会话里往同一主题发布一条消息。如果订阅端能收到消息说明 Broker 的消息路由完全正常。这个测试看起来简单但它是后面所有物联网业务的基础建议耐心做一遍。5.2 用 mosquitto 命令行工具测试有时候服务器上没有图形界面或者想写脚本做自动化测试那就用命令行工具。这里推荐安装mosquitto-clients里面包含mosquitto_pub和mosquitto_sub两个命令。订阅端mosquitto_sub -h 服务器IP -p 1883 -u 用户名 -P 密码 -t test/topic发布端mosquitto_pub -h 服务器IP -p 1883 -u 用户名 -P 密码 -t test/topic -m hello from cli如果订阅端终端能打印出hello from cli说明命令行链路也通了。这条链路由几个环节组成客户端 TCP 连接 EMQX - EMQX 完成认证 - 订阅端注册到test/topic- 发布端消息进入 Broker - Broker 路由给订阅端。任何一个环节出问题消息都到不了对端。这也是排查问题的好思路先确认连得上再确认发得出收得到。5.3 生产环境常见的接入场景说明连接测试跑通之后你的 MQTT 服务器就算真正可用了。我简单列几个实际项目中常见的接入场景帮助你理解这个服务器在日常系统中承担什么角色。场景一是设备数据采集。硬件端用 ESP32、STM32 或者 4G 模块通过 MQTT 上报温度、湿度、电压等数据到 Broker后端服务订阅对应主题把数据写入数据库做存储和展示。这种场景下设备数量可能是几十台到几万台EMQX 的高并发连接能力就派上用场了。场景二是指令下发。管理平台需要远程控制设备比如打开继电器、调整设备参数。平台端作为 MQTT 客户端向设备的主题发布控制消息设备端订阅自己的主题就能收到指令。这里可以结合遗嘱消息设备意外断线时 Broker 会帮设备向指定主题发布一条离线消息平台就知道设备掉线了。场景三是数据桥接。EMQX 的规则引擎可以把某个主题的数据直接转发到后端 HTTP 服务、Kafka、数据库等。这样设备数据不需要经过任何中间环节EMQX 本身就是数据处理管道的第一站。这种架构日常维护起来非常省心因为设备侧、消息中间件侧、业务侧各自独立出了问题可以快速定位在哪一段。6. 常见问题与排查实录6.1 客户端连不上先分清是哪一层的问题我遇到过最多的问题就是连不上。连不上这个问题首先要分清楚是 TCP 层连不上还是 MQTT 认证失败还是 Broker 根本没启动。我习惯按这个顺序排查。第一步看进程和端口。sudo docker ps确认容器在跑sudo netstat -tlnp | grep 1883确认端口在监听。如果端口没在监听看 Docker 日志里有没有异常报错。第二步测 TCP 连通性。在客户端机器上执行telnet 服务器IP 1883如果连接被拒绝或者超时说明 TCP 层有问题重点检查安全组、防火墙和端口映射。如果 telnet 能通说明网络没问题问题大概率出在 MQTT 层。第三步看认证。如果 TCP 能通但 MQTT 连接报Not authorized那就是认证没通过。检查一下账号密码是否正确Dashboard 里是否关闭了匿名认证但客户端没填账号或者填的账号不是 Broker 认证源里存在的。第四步看日志。sudo docker logs emqx和/opt/emqx/log目录下会有详细记录。连接失败时日志里通常会有具体标识比如客户端 ID、失败原因等能帮你快速缩小范围。6.2 端口映射和防火墙的坑部署过程中最容易让人抓狂的是端口问题。我在一台云服务器上部署 EMQX启动容器后自己 curl 本机 18083 能通但从办公室电脑访问就超时。排查了一圈才发现云服务商的安全组规则里没有放行 1883 和 18083 端口只放行了常用的 22 和 80。这里有个经验云服务器的防火墙有安全组和系统防火墙两层两层都要放行。有些云厂商的安全组默认是白名单模式不主动加规则端口就是不通。检测时可以临时用nc -vz 服务器IP 端口或者 telnet 试一下只要有一个超时优先去看安全组。另外还要注意EMQX 容器映射端口时宿主机端口和容器端口都需要被监听-p 1883:1883中第一个 1883 是宿主机端口第二个是容器内端口映射关系别搞反。6.3 规则引擎做数据转发的一个实例这里分享一个规则引擎的简单用法也是我实际用过的场景。假设设备往devices/sensor_001/data主题发送 JSON 数据{temperature: 28.5, humidity: 60}我想在温度超过 30 度时把数据转发到一个告警主题alerts/high_temperature。在 EMQX 5.x 的 Dashboard 里进入规则模块新建一条规则SQL 可以写成这样SELECT payload.temperature as temp, payload.humidity as hum, topic as t FROM devices//data WHERE payload.temperature 30然后给这条规则添加一个动作选择消息重新发布目标主题填alerts/high_temperature。这样温度数据一超过阈值告警消息会自动出现在告警主题里后端服务只需要订阅这个主题就能实时处理。整个过程不需要写任何后端代码规则引擎在 Broker 内部就完成了。这个能力是 EMQX 区别于轻量级 Broker 的核心优势之一。你可以在 EMQX 里把大量数据预处理逻辑下沉到消息中间件让业务系统专注于更上层的功能。6.4 性能与资源建议最后聊一聊性能相关的问题。EMQX 5.x 单节点可以支撑几十万并发连接这是官方宣传的数字实际取决于服务器配置、连接行为和消息大小。我自己跑过一个小规模测试2 核 4G 的云主机稳定支撑了上万台设备的连接和每秒几千条消息的转发CPU 和内存都还有明显余量。如果你预计连接规模不会特别大单节点完全够用不必一上来就搭集群。集群的价值在于高可用和水平扩展如果业务要求 Broker 宕机不影响生产再考虑多节点集群加负载均衡。集群部署比单机复杂得多建议先把单节点用熟再按需扩展。资源方面需要关注三个指标连接数、消息 TPS、消息体积。连接数高时注意内存占用消息量大时关注 CPU 和网络带宽消息体积大时要检查是否承载了不必要的字段。我在生产环境遇到过一次内存缓慢增长的问题排查下来发现是某些客户端使用 QoS 2 发送大量消息消息重发堆积导致资源占用上升。后来限制客户端 QoS 等级、定期清理不活跃连接问题就缓解了。最后补充一点个人体会整个部署过程走下来我最想说的是EMQX 的上手门槛比想象中低很多但生产的坑往往不在 EMQX 本身而在周边的网络、认证、持久化这些容易被忽视的环节。Docker 部署让它变得极其轻量但如果你忘了挂载数据卷、忘了关匿名认证、忘了配安全组后面总会以各种方式找回来。我自己是在发生了容器删掉配置全没的事故之后才开始认真对待部署清单这件事。现在我的部署流程基本固定先规划端口再写 Compose 文件启动后第一时间改管理员密码、关匿名认证、创建客户端账号最后用 MQTTX 做一轮连接和收发测试。整套流程下来出问题的概率低了很多。如果你后续要把 EMQX 做得更深入可以重点玩玩这几个方向规则引擎的数据桥接转发到数据库或 Kafka、TLS 加密通信、多节点集群部署。每一样都有不少可聊的细节等你有具体需求的时候再来蹲我的下一篇文章。