最近在帮朋友搭一套设备远程监控系统,核心需求其实很朴素:几十个传感器节点要定期上报温湿度、电压、状态位这些数据,服务器要能随时拿到,偶尔还要反向发一条指令给某个设备。一开始想用HTTP轮询,但设备端网络不稳定、IP经常变,sleep和重试逻辑写起来又臭又长,后来直接上了MQTT,服务端选的就是EMQX——这也是今天这篇博文的主题:MQTT服务(EMQX)安装。
先简单说下这东西是干嘛的。MQTT是专门为物联网场景设计的轻量消息协议,走发布/订阅模式,设备端只管往某个主题(Topic)丢消息,服务端负责转发,谁订阅了这个主题谁就能收到。EMQX就是那个“服务端”,一个基于Erlang/OTP开发的开源MQTT消息代理(Broker)。它能干什么?扛海量并发连接、支持毫秒级消息路由、自带规则引擎和Dashboard管理界面,装好之后设备接入、数据转发、远程控制这一整套底座就有了。适合谁看?准备搞智能家居、工业数据采集、车联网,或者单纯想给自己的项目搭一个消息通道的同学,这篇实操笔记都能直接用。
我没打算把官方文档翻译一遍,而是按照自己从零到一搭起来的完整过程来写,包括选型时的纠结、安装方式对比、踩过的坑,希望对你有实际帮助。
1. 为什么我用EMQX搭MQTT服务而不是自己造轮子
1.1 MQTT到底解决了什么问题
在没有MQTT之前,如果我有几十台设备要上报数据,常规思路是让每台设备定时往服务器发HTTP请求。听起来挺简单,但做起来全是坑。设备在局域网里,没有公网IP,服务器根本没法主动找到它,只能靠设备主动上报,想做远程控制就很别扭。就算设备能主动上报,弱网环境下请求超时、重试风暴、服务端并发压力,每一个都要自己处理。
MQTT把这个问题变成了“大家共用一个消息管道”。设备上线后跟Broker保持一条长连接,数据发到Broker,订阅方从Broker收。它有几个特性是物联网场景非常受用的:
- 长连接低开销:一个TCP连接可以承载海量消息,报文头最小只有2个字节,对流量敏感的场景很友好。
- 发布/订阅解耦:生产者和消费者互不感知,设备离线在线不影响彼此收发逻辑。
- QoS分级:消息可以按0、1、2三级投递,从“最多一次”到“恰好一次”,按需求取舍可靠性和开销。
- 遗嘱与保留消息:设备异常掉线时Broker可以代发遗嘱消息通知订阅方;保留消息能让新订阅者立刻拿到最新状态。
这套模型特别适合“设备上报 + 平台下发控制指令”的双向通信场景。我做的这个监控系统,传感器网关用MQTT把数据发上来的同时,平台也能往特定主题下指令,整个链路清爽很多。
1.2 市面上的MQTT Broker那么多,为什么选EMQX
不夸张地说,MQTT Broker的选项从轻到重一大堆:轻量级的有Mosquitto,重量级的有EMQX,还有商业化产品如HiveMQ,国内也有各种物联网平台的私有Broker。我的选择逻辑主要看三点:
- 连接承载能力:Mosquitto单节点处理几千个连接是没问题的,但如果未来要撑几万甚至几十万并发连接,就要上集群方案。EMQX天生基于Erlang/OTP的Actor模型,单节点就能扛百万级连接,横向扩展也比较平滑,留给后续业务增长的空间大。
- 功能生态:EMQX内置了规则引擎、数据桥接、认证鉴权、Dashboard监控,数据来了可以直接转发到MySQL、Kafka、Webhook等,省去自己写一堆转发逻辑。
- 社区与部署便捷度:EMQX开源版功能够用,文档完善,提供Docker镜像、二进制包、apt/yum源多种安装方式,对一个中小团队或个人开发者来说,试错成本非常低。
当然,如果只是在家里小规模用,比如三五块开发板,Mosquitto完全够用,配置还更简单。但既然项目后续可能从测试环境往生产环境演进,我直接选了EMQX,省得中途再迁移。
2. 安装前的脑内推演:环境与安装方式选型
2.1 硬件和环境怎么给
EMQX本身是Erlang写的,对CPU和内存有一定要求,但不像数据库那样吃硬盘IO。官方给的建议是生产环境至少2核4G,开发测试1核1G也能跑起来。我这次的部署环境是一台2核4G的Linux服务器,操作系统是Ubuntu 22.04,单机部署,暂时不涉及集群。
端口方面,几个默认端口先心里有数:
| 端口 | 用途 |
|---|---|
| 1883 | MQTT over TCP,设备接入主端口 |
| 8883 | MQTT over SSL/TLS,加密接入 |
| 8083 | MQTT over WebSocket |
| 8084 | MQTT over WSS,浏览器/小程序接入 |
| 18083 | Dashboard管理界面 |
很多人在安装完成后发现设备连不上,打开服务器防火墙一看才发现1883没放行,所以提前把端口规划好能省不少事。
2.2 四种安装方式怎么选
EMQX提供这么几种主流安装路径:
- Docker容器:一条命令拉镜像启动,环境隔离,升级回滚方便,适合大部分场景。
- APT/YUM系统包:用官方仓库或发行版仓库安装,能用systemd管理服务,适合不想用容器、想跟系统集成更紧密的服务器。
- 二进制压缩包:官方提供zip/tar.gz包,解压即用,适合无外网或需要内网部署的环境。
- 源码编译:最灵活也最折腾,要自己装Erlang、编译依赖,除非有定制需求,否则真没必要。
我做技术选型有个习惯,按场景而不是按“哪个技术更酷”来决定。Docker方式最适合开发和中小规模生产,所有依赖都打包在镜像里,不会污染宿主机。如果项目要部署到客户的离线服务器上,再换成二进制包也不费劲。所以这次的主安装路径选Docker,同时我也会把tar.gz包安装的步骤完整走一遍,方便没有Docker环境的时候应急。
3. 实操:三套安装方案走一遍
3.1 Docker部署EMQX,我首推的方式
服务器上已经装好了Docker,如果没有,先装一下:
sudo apt update sudo apt install -y docker.io sudo systemctl enable --now dockerEMQX官方镜像有多个发行系列,当前主流是5.x。相比4.x,5.x在配置方式、Dashboard交互、数据集成上都有明显变化,新项目直接用5.x:
docker pull emqx/emqx:5.8.3我这里固定了具体版本号而不是直接用latest,原因很简单:生产环境要可预期,镜像版本漂移很容易导致行为不一致。跑容器前先建好数据目录,把可能变化的数据和配置挂载出来:
mkdir -p /opt/emqx/{data,etc,log} docker run -d --name emqx \ --restart unless-stopped \ -p 1883:1883 \ -p 8083:8083 \ -p 8084:8084 \ -p 18083:18083 \ -v /opt/emqx/data:/opt/emqx/data \ -v /opt/emqx/etc:/opt/emqx/etc \ -v /opt/emqx/log:/opt/emqx/log \ emqx/emqx:5.8.3启动之后检查状态:
docker ps | grep emqx docker logs emqx --tail 50日志里能看到“EMQX 5.8.3 is running”之类的字样,说明起来没问题。浏览器访问http://服务器IP:18083,默认账号admin、密码public,登录后建议立刻改掉。
挂载目录这件事我多说一句:不挂载也能跑,但容器一旦删除重建,配置和消息数据就全没了。IoT场景里设备的离线消息、遗嘱消息可能都在Broker里有状态,养成挂载数据卷的习惯很重要。
3.2 二进制包安装:离线环境下的另一条路
最开始我不打算用Docker的那台内网服务器,就试了二进制包安装。从官网下载页拿对应系统的tar.gz包:
wget https://www.emqx.com/en/downloads/broker/5.8.3/emqx-5.8.3-ubuntu22.04-amd64.tar.gz tar -zxf emqx-5.8.3-ubuntu22.04-amd64.tar.gz cd emqx # 解压出来的目录名一般是 emqx这个包内置了Erlang运行时,不需要额外安装Erlang环境,这一点在离线部署时尤其省心。启动命令是:
./bin/emqx start检查状态:
./bin/emqx ctl statusNode emqx@127.0.0.1 is started说明启动成功。停止用./bin/emqx stop,查看运行详情用./bin/emqx ctl broker。
macOS系统也有对应包,不过一般开发测试用Docker,二进制包主要用于Linux服务器。另外提醒一下,解压目录不要放在root用户目录之外容易被清理的临时路径,建议统一放到/opt/emqx,配合systemd管理服务,方便长期部署。
3.3 APT/YUM源安装的一些补充
如果服务器能联网,又不想用Docker,可以考虑用官方APT源。它的好处是能跟着系统包管理工具做升级,坏处是官方源在国内访问速度有时不太理想。大致步骤:
curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash sudo apt-get install -y emqx sudo systemctl start emqx安装后配置文件在/etc/emqx/emqx.conf,日志在/var/log/emqx/,数据默认也在/var/lib/emqx/。这种安装方式适合已经用systemd管理整套服务、不想引入容器编排层、希望EMQX无缝接入监控体系的环境。
3.4 源码编译安装,什么情况下才用
源码编译大概是三年前我干过的事,当时为了加一个自定义插件必须从源码构建。步骤上需要提前装好Erlang/OTP版本、依赖库,然后执行configure/make流程。这里不展开细节,只做一句总结:EMQX的官方二进制包已经带了编译好的Erlang运行时,普通用户根本不需要从源码编译,除非你要改EMQX内部代码或做深度二次开发。
4. 启动后的配置与验证:别装完就跑
4.1 关键配置项逐条说
安装只是第一步,真正决定“能不能用得好”的是配置。Docker方式下,修改配置有两种路径:一是改/opt/emqx/etc/emqx.conf后重启容器,二是在docker run时用环境变量覆盖。我这次主要用环境变量方式改几个关键选项:
docker run -d --name emqx \ -e EMQX_DASHBOARD__DEFAULT_PASSWORD="mySecurePassword123" \ -e EMQX_AUTHENTICATION__USERNAME=admin \ -e EMQX_AUTHENTICATION__PASSWORD=mqtt_pass_2025 \ ...外部客户端接入的默认监听器相关配置在5.x里通过EMQX_LISTENERS__TCP__DEFAULT__BIND这类环境变量控制。如果你用二进制包,则直接在etc/emqx.conf里改:
listeners.tcp.default { bind = "0.0.0.0:1883" max_connections = 1024000 }生产环境有几个点需要特别上心:
- max_connections:默认值是很大的,但如果服务器资源有限,建议限制一个合理值,防止设备浪涌把Broker挤爆。
- force_shutdown:默认会在系统内存达到阈值时自动重启节点,这是一个保护机制。内存不充足的机器可以调低阈值。
- authentication:默认是允许匿名连接的,生产环境必须开启密码认证,不然任何设备都能订阅你的数据流,相当于是把消息通道裸奔在大街上。
我之前测试时图省事没开认证,结果设备列表里突然多出来几个陌生连接,一查IP是外网的扫描行为。从那一刻起,我所有实测环境都强制开了认证。
4.2 用命令行和客户端做连通性验证
服务启动后,第一步验证Broker是不是真能收发消息。最简单的方式是用Linux下的mosquitto客户端工具:
# 安装客户端工具 sudo apt install -y mosquitto-clients # 订阅主题 mosquitto_sub -h 127.0.0.1 -p 1883 -t "test/topic" -v # 另开终端,发布一条消息 mosquitto_pub -h 127.0.0.1 -p 1883 -t "test/topic" -m "hello emqx"如果sub端能实时打印出test/topic hello emqx,说明Broker的TCP接入链路是通的。开认证后记得加-u admin -P 密码参数。
图形化工具我推荐MQTTX,它是个跨平台桌面客户端,能直观地看连接状态、收发消息、查看遗言消息,小白用它入门特别快。用MQTTX创建一个连接,填服务器IP、端口1883、用户名密码,连接成功后往test/#发几条消息,然后在Dashboard的主题监控里看流量曲线,能明显看到日志与收发消息的联动。
4.3 Dashboard里值得关注的几个页面
EMQX的Dashboard是它的重要卖点,登录后建议重点看四个地方:
- 连接与订阅:实时显示在线客户端数量、订阅关系、上下线事件,排查设备异常断线时先看这里。
- 主题与消息指标:显示消息收发速率、丢弃消息数、QoS分布情况,压力测试时的数据从这里拉。
- 告警与日志:配置告警规则,比如“连接数超过阈值”“消息积压过多”,让系统主动通知你,不用每天蹲屏幕。
- 认证与授权管理:在这里配置账号、密码、ACL权限,比手改配置文件直观很多。
我搭完这套系统后,基本每天登录Dashboard扫一眼连接曲线,一旦发现异常波动,马上能从连接列表里定位是不是某个设备在疯狂重连。
5. 真踩过的坑:常见问题与排查速查表
5.1 端口占用和防火墙问题
排查经历里出现频率最高的就是“装好了但外部连不上”。某次我在云服务器上装完EMQX,MQTTX死活连不上,本地命令行却能连,立刻排查系统防火墙:
sudo ufw status sudo ufw allow 1883/tcp sudo ufw allow 18083/tcp如果是云服务商的安全组,还要到控制台放行对应端口。这个坑真的很基础,但太容易忽略了,尤其是那种“本地能跑、远程上不去”的场景,十有八九是安全组或防火墙没放行。
5.2 认证失败与连接频繁断开的排查
开了密码认证后,设备端报CONNACK (5) - Connection Refused: not authorized,几乎都是用户名或密码不对。还有一个隐蔽情况:配置了用户但没给客户端分配正确的ACL权限,导致能连接但不能收发消息。排查优先级建议是:先看认证配置,再看ACL规则,最后看客户端是否指定了错误的clientId或用户名。
设备频繁掉线也是一个高频问题。之前有一批设备每隔几十秒就断开重连,把服务器连接数顶得贼高。排查时发现是设备端的心跳间隔设置的太长,超过Broker的session_expiry_interval,Broker认为会话过期就把连接回收了。解决办法是调整设备端keep alive,或者在EMQX里放宽会话超时时间,并根据设备网络状况合理配置心跳。
5.3 消息积压和内存占用过高的预警
消息积压通常出现在“生产速度远大于消费速度”的场景。比如某个规则引擎的转发目标数据库写挂了,数据桥接失败,消息就会在Broker里堆积,表现为内存持续上涨。遇到这种情况,我先去Dashboard看各主题的消息速率积压情况,再查数据桥接的失败日志,确认是目标服务不可用还是配置错误。修复后的习惯是给告警规则加“消息堆积数量超过10000”时触发通知,避免再被突袭。
5.4 配置文件改完不生效的两种原因
一是改错了配置文件,5.x版本的emqx.conf路径和4.x有差异,容器内路径是/opt/emqx/etc/emqx.conf,但环境变量优先级更高,你改了文件却被环境变量覆盖了。二是改了配置没重启或者没reload。遇到“明明改了却没效果”,先查当前生效的配置值:
docker exec -it emqx emqx ctl conf show这样能直接看出配置是否真正生效,比翻日志快得多。
再补一个操作习惯:批量修改EMQX配置时,建议总是先备份一份原始配置,改完用bin/emqx ctl check_config之类的命令验证语法合法性,再做服务重载。这样能最大限度避免一次改一堆参数导致加电起不来的尴尬。
6. 最后分享几个我摸索总结出来的小习惯
第一,Docker部署的容器启动参数里一定要带--restart unless-stopped,这样宿主机重启后EMQX能自动拉起来,设备群不会因为Broker没起来而集体掉线。
第二,养成“先在测试环境试新版本,再上生产”的习惯。EMQX从4.x升到5.x的过程中,配置语法和数据桥接方式变化不小,直接在生产环境升级很容易踩兼容性坑。我在另一台测试机上先把5.8.3验证完整,再决定生产环境迁不迁移。
第三,保存好Dashboard的默认账号密码后,建议关闭或限制外网访问18083端口。Dashboard虽然是管理界面,功能很强大,但这意味着它也是攻击者最喜欢的目标。把管理端口在安全组里限制为只允许办公网IP访问,安全性会好很多。
这几个小习惯都不是什么高深技巧,但叠加起来,能让一套MQTT服务少很多半夜三更的告警。EMQX的安装本身不难,难的是装完之后把认证、网络、监控这些周边配套都补齐。希望这篇实操笔记能帮你少走几步弯路,顺利把第一套MQTT服务跑起来。如果你在安装过程中遇到其他怪问题,欢迎对照上面的排查表逐项验证,大部分“装好但不好用”的烦恼都能在那张表里找到答案。