Ubuntu 20.04部署EMQX:MQTT物联网消息中间件搭建全攻略

发布时间:2026/10/7 4:03:48
Ubuntu 20.04部署EMQX:MQTT物联网消息中间件搭建全攻略 接手一个物联网项目第一步往往是搭消息中间件。手上正好有一台Ubuntu 20.04的服务器需要跑MQTT服务我选了EMQX。这篇博客就把从零开始到跑通的完整记录放出来包括关休眠、换国内源、装EMQX、配账号密码、订阅发布实测以及排查坑位按步骤可复现适合刚接触物联网消息服务的读者。1. 方案选型与部署架构1.1 为什么是EMQX而不是Mosquitto物联网场景下的消息中转很多人的第一反应是Mosquitto轻量、单机部署快学起来一小时就够。但一旦接入的设备量上来需要集群、规则引擎、数据桥接Mosquitto就得自己拼一堆插件。我这次选EMQX核心原因是它把物联网常用的能力全做进了内核多协议接入不止MQTT还支持MQTT-SN、CoAP、LwM2M后续如果接非MQTT设备不用再换中间件。内置规则引擎可以从消息里提取字段直接转发到InfluxDB、MySQL、Kafka省去写转发服务的成本。集群原生节点之间自动发现水平扩展非常平滑。Dashboard可视化连接数、消息速率、订阅关系一目了然排障效率比纯命令高得多。从资源占用来看EMQX的Erlang/OTP虚拟机确实比Mosquitto吃内存空闲时约150MB左右但在2核4G的机器上跑几十台设备完全没压力。如果你只是在校验车上调几个传感器那Mosquitto足够了如果想做一个长期运营的物联网平台底座直接上EMQX省得后面迁移。1.2 MQTT协议的三个关键角色在动手安装前必须把MQTT的基本模型搞清楚。MQTT里永远有三个角色角色作用类比Broker消息中转中心就是EMQX邮局Publisher发送消息的客户端寄信人Subscriber订阅并接收消息的客户端收信人三者通过**主题Topic**联系起来。比如温湿度传感器发布一条消息到sensor/room1/temp监控大屏订阅了这个主题就能实时收到数据。MQTT的订阅支持通配符sensor//temp匹配所有房间的温度#匹配多层级所有主题这是MQTT最灵活的地方。还有两个关键机制QoS服务质量和遗嘱消息Last Will。QoS 0最快但可能丢消息QoS 1至少一次但可能重复QoS 2恰好一次但性能最差。我在实际项目里默认用QoS 1其次是QoS 0。遗嘱消息则是设备断线时由Broker替它广播一条“我挂了”的消息这是做设备在线监控的利器后面配置账号时会提怎么验证。1.3 版本选择与资源规划这一版选EMQX很关键。目前官方提供的版本主要有4.x和5.x两条线EMQX 4.x经典版文档丰富网上教程多插件机制熟悉很多老项目还在用。EMQX 5.x当前主力Dashboard改版大配置支持HOCON格式Dashboard操作更顺手资源占用优化明显。新项目建议直接上5.x我这里用的是5.8的社区版Open Source版。社区版足够支持生产级单机部署只有集群管理、热配置等企业功能被限制个人学习和小规模商用没问题。资源规划方面在Ubuntu 20.04上跑EMQX最低配1核1G也能启动但建议至少2核2G磁盘留10GB以上用于日志和消息堆积。我测试机是2核4G实测连接200个客户端、每秒500条消息时CPU占用约20%内存约500MB完全扛得住。2. 环境准备与Ubuntu基础调优2.1 关闭休眠功能避免部署中断这是Ubuntu 20.04服务器部署最容易踩的坑。默认桌面版Ubuntu会挂起系统服务器长时间SSH操作后突然断连多半是休眠触发了。Ubuntu 20.04使用的是systemd管理电源状态先检查当前休眠配置systemctl status sleep.target suspend.target hibernate.target hybrid-sleep.target如果状态不是inactive直接禁用sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.targetmask和disable的区别要理解一下。disable只是取消开机启动系统仍然可以通过其他方式触发休眠mask则是彻底屏蔽连手动执行的入口都堵死。服务器场景必须用mask。另外还要检查桌面环境自带的电源管理设置GNOME桌面的设置在“设置”-“电源”里把“自动挂起”改为“从不”。如果用的是最小化服务器版没有桌面只需上面的systemctl命令就够了。还有一个细节禁用休眠后建议同时修改SSH断连保护参数防止临时掉线导致安装中断。编辑/etc/ssh/sshd_config找到ClientAliveInterval和ClientAliveCountMax改为ClientAliveInterval 60 ClientAliveCountMax 3这样SSH每60秒发一次心跳包允许连续3次超时180秒内网络抖动不会断开连接。2.2 换用国内源加速安装更新Ubuntu 20.04官方源在国内有时速度感人安装依赖可能要等几分钟。这里直接把软件源替换为阿里云镜像。先备份原配置sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak然后编辑/etc/apt/sources.listsudo sed -i s/archive.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list sudo sed -i s/security.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list如果之前用的是清华源之类想统一替换也更简单直接清空文件写入deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse写完后刷新索引sudo apt update sudo apt upgrade -y顺手装上后续排查会用到的工具sudo apt install -y net-tools curl wget nano mosquitto-clientsmosquitto-clients这一步很多人会忽略。它自带mosquitto_pub和mosquitto_sub命令行工具测试MQTT消息发布订阅非常方便不用专门开IDE写测试代码。2.3 防火墙与端口放行EMQX默认占用下面几个端口部署前要规划好防火墙策略端口用途1883MQTT TCP协议端口8883MQTT TLS/SSL加密端口8083WebSocket端口浏览器场景用8084WSS加密WebSocket端口18083Dashboard管理控制台端口4370集群节点间通信端口如果启用了ufw防火墙需要放行这些端口。只放行生产必要的端口sudo ufw allow 1883/tcp sudo ufw allow 18083/tcp sudo ufw allow 8083/tcp sudo ufw status注意如果是云服务器光改系统防火墙还不够必须同步在云控制台的安全组里放行端口。我遇到过本地ufw全开放了但外网死活连不上的情况最后发现是云安全组默认只放行22端口这个问题很多新手会忽略。测试期间如果图省事可以临时关闭防火墙但生产环境务必保持开启并且只放行必要端口。3. EMQX安装与基础配置3.1 通过APT仓库安装官方提供两种安装方式APT仓库和Docker。先讲APT方式这是最推荐的生产部署方式配置管理、日志、systemd服务都走标准路径。EMQX提供了专门的APT仓库安装时先导入仓库信息# 安装基础工具 sudo apt update sudo apt install -y curl gnupg apt-transport-https # 添加EMQX官方GPG密钥 curl -fsSL https://packages.emqx.net/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/emqx.gpg # 添加APT源 echo deb [signed-by/usr/share/keyrings/emqx.gpg] https://packages.emqx.net/emqx-ce/deb/ubuntu focal main | sudo tee /etc/apt/sources.list.d/emqx.list # 刷新源并安装 sudo apt update sudo apt install -y emqx关于codename有个细节EMQX的APT源对20.04用focal18.04用bionic22.04用jammy别写错不然后面依赖解析会出问题。启动服务并设置开机自启sudo systemctl start emqx sudo systemctl enable emqx systemctl status emqx看到active (running)就说明安装成功。安装完后默认Dashboard地址是http://你的服务器IP:18083默认管理员账号密码是admin/public首次登录会强制要求修改密码。再验证一下MQTT端口是否在监听sudo netstat -tlnp | grep 1883 tcp6 0 0 :::1883 :::* LISTEN 12345/beam.smp看到1883端口监听就对了。这里的进程名是beam.smpEMQX底层Erlang虚拟机的进程名看到这个不用慌。3.2 Docker方式对比参考如果你的服务器上已经跑了不少Docker容器用Docker部署EMQX也不差对隔离环境尤其方便# 拉取并启动容器 docker run -d --name emqx \ -p 1883:1883 \ -p 8083:8083 \ -p 18083:18083 \ -e EMQX_DASHBOARD__DEFAULT_PASSWORD你的密码 \ emqx/emqx:5.8Docker方式的限制主要在配置持久化上。容器内/opt/emqx/data是数据目录必须挂载到宿主机docker run -d --name emqx \ -p 1883:1883 -p 8083:8083 -p 18083:18083 \ -v emqx-data:/opt/emqx/data \ -v emqx-log:/opt/emqx/log \ emqx/emqx:5.8否则容器一删配置全丢。这个坑我踩过升级EMQX版本后直接照搬老容器配置没挂数据卷所有用户、规则引擎、认证设置全部重置教训极其惨痛。个人还是更喜欢APT方式因为升级用apt upgrade emqx就行配置路径固定排查文档也好对。Docker适合快速体验和多套环境隔离生产环境建议二选一后保持统一。3.3 Dashboard初始化与基本设置通过浏览器访问http://IP:18083第一次登录会看到初始化界面。这里要做的核心事情就一件改掉默认管理员密码。登录后进入 Dashboard每个版本的界面可能有差异但设置逻辑一致左侧菜单找“管理”-“用户管理”修改admin用户的密码。确认版本号与节点状态正常默认只有一个节点状态为Running。检查系统内存和连接数指标确认无异常报警。Dashboard右上角能看到当前连接数、订阅数、消息流入流出速率这四个数字是判断服务是否健康的第一抓手。心跳正常但消息收发为0大概率是订阅主题不匹配消息流入有数值但流出为0一般是订阅端没有连上来。这种监控视角比看日志快得多。提示如果18083端口无法访问先本地curl试一下curl -I http://127.0.0.1:18083。本机能通外网不通查防火墙和安全组本机都不通查emqx服务状态和端口监听。4. 账号密码与访问控制配置4.1 内建认证添加用户EMQX刚装好时MQTT客户端可以匿名连接生产环境必须关掉。我选择用内置数据库认证Built-in Database不需要额外依赖配置简单。在Dashboard左侧菜单进入“访问控制”-“认证”点击“创建”按钮认证方式选择“密码认证”Password-Based后端类型选择“内置数据库”Built-in Database数据源默认选中“内置数据库”即可保存后全局认证即启用然后在“访问控制”-“用户管理”里“添加用户”填入客户端ID和密码。这里有个常见误区EMQX的用户名Username和MQTT的Client ID是两个概念。Username是认证凭据Client ID是连接标识两者可以相同也可以不同。规则引擎处理时通常两侧都能拿到。我实际项目中习惯按设备类型规划用户名比如device_temp_001、gateway_485_01密码生成随机串并写入设备端配置。注意EMQX的密码不支持明文直接入库5.x版本会自动使用BCrypt算法做哈希创建用户时只需要填明文密码系统自动加盐处理。配置完成后需要再确认“认证”页面里的状态是启用。另外每添加一个用户后建议点一次“测试”按钮用刚配置的账号密码测试连接是否通过避免设备端配错了才排查。4.2 客户端连接与验证配置完账号后立即用命令行验证不要等设备接入才发现问题。使用前面装的mosquitto-clients工具# 订阅一个测试主题 mosquitto_sub -h 127.0.0.1 -p 1883 -u device_temp_001 -P 密码 -t test/topic -v # 另开一个终端发布消息 mosquitto_pub -h 127.0.0.1 -p 1883 -u device_temp_001 -P 密码 -t test/topic -m {temp:25.6}订阅端收到JSON消息就说明整条链路通了。这里两个工具没加--debug参数如果连不上建议加上-d参数看完整交互过程mosquitto_sub -d -h 127.0.0.1 -p 1883 -u device_temp_001 -P 密码 -t test/topic如果看到Connection Refused: not authorised说明用户名密码不对或者认证配置没生效。如果看到Connection Refused: connection refused则是服务没起来或端口错。再验证一下匿名是否已被拦截。故意不带用户名和密码连接mosquitto_pub -h 127.0.0.1 -p 1883 -t test/topic -m no auth这条命令应该报错因为认证已经启用。如果它成功发出了说明认证配置没有真正生效去Dashboard检查全局认证状态是否为启用。还有遗嘱消息的验证。发布端指定遗嘱后强制断开mosquitto_pub -h 127.0.0.1 -p 1883 -u device_temp_001 -P 密码 -t device/status -m {online:true} --will-topic device/status --will-payload {online:false} --will-qos 1订阅device/status的终端会在publish端断开后收到{online:false}这就是设备离线检测的基础和485设备网关对接时会经常用到这个机制。5. MQTT订阅发布消息实战与场景扩展5.1 对接485设备的数据读取与指令下发MQTT最常见的物联网落地场景就是采集Modbus RTU设备数据再让上层应用通过MQTT下发控制指令。整个链路是485设备 - Modbus网关 - MQTT Broker (EMQX) - 数据平台/业务系统Modbus网关通常支持MQTT直接上报数据。以我手里的某款网关为例它配置了MQTT连接参数后会自动将Modbus寄存器数据发布到主题gateway/device1/data载荷格式类似{register:40001,value:156,timestamp:1699950000}平台侧订阅该主题即可实时入库。指令下发时平台向gateway/device1/command主题发布消息{register:40003,value:1,action:write_single}网关收到后会解析指令并转为Modbus写操作回复结果再发布到gateway/device1/response。这套模式的关键在于消息格式必须前端先行约定寄存器地址、字节顺序、数据类型都要在协议文档里写死否则上线后联调会非常痛苦。Kingscada这类组态软件也是走同样的套路。Kingscada自带的MQTT客户端插件本质就是一个Subscriber配置好Broker地址、Topic格式、JSON节点映射就能把MQTT数据拉进组态画面。对应的订阅主题和字段映射规则必须在EMQX侧先创建一个测试账号然后用mosquitto_pub模拟设备发一条完整报文给Kingscada端验证字段是否对齐。5.2 使用MQTTX图形化工具调试命令行工具验证链路没问题后建议再装一个MQTTX。这是目前最好用的MQTT客户端调试工具支持跨平台配置文件可导出新建连接填入EMQX的IP、端口、Username、Password。添加订阅填写test/topic点击订阅消息列表会实时显示。发布消息Payload可以选JSON格式支持格式化展示非常直观。用MQTTX的好处是能在同一界面同时管理多个连接模拟多个设备并行测试。我在测试多设备并发时会开三四个MQTTX连接分别用不同的账号和Topic标签来模拟不同房间的设备比命令行切换终端高效很多。MQTTX还有个特性是可以通过WebSocket连接EMQX的8083端口。这对应浏览器中的MQTT over WebSocket场景如果之后要做网页版设备监控大屏这个能力后面直接用得上。5.3 规则引擎转发数据扩展知识5.x版本里规则引擎替代了4.x的数据桥接插件。在做数据落库时Dashboard左侧“规则”-“创建规则”里填SQL例如SELECT payload.temp as temp, payload.humidity as humidity, clientid as client_id, timestamp as ts FROM test/topic WHERE payload.temp 30这里的SQL语法类似但并非标准SQLFROM后跟的是订阅主题payload提取用点号语法。规则创建后要接一个“动作”比如保存到MySQL。这个方向如果展开篇幅很大这里只提个思路规则引擎可以实现“温度超过阈值自动告警”“数据实时入库”等效果是EMQX相比Mosquitto的最大优势。6. 常见问题与排查技巧实录6.1 典型问题速查表把部署到现在遇到的典型问题整理成一张表方便对照处理故障现象可能原因排查方法服务启动失败端口被占用sudo netstat -tlnp | grep 1883Dashboard无法访问防火墙/安全组未放行18083本地curl测试再查防火墙配置客户端连接被拒绝未启用认证或账号密码错误mosquitto_sub -d查看报错信息客户端认证失败密码哈希算法不匹配Dashboard重新创建用户订阅收不到消息Topic不通配或QoS不匹配检查主题字符串是否完全一致消息发不出去QoS为0且网络抖动丢消息升级QoS级别或检查网络质量连接数满了默认配置了最大连接数Dashboard查看连接数与系统限制搭建好无法外网访问云平台安全组未放行登录云控制台检查安全组规则6.2 收不到消息的排查思路“收不到消息”是MQTT排查里最常见的问题。我处理这类问题有一套固定检查顺序连接是否成功在订阅端和发布端都加-d参数看是否CONNECT成功。主题是否精确一致MQTT对大小写敏感Test/topic和test/topic是两个完全不同的主题。通配符是否按预期工作sensor/#能匹配sensor/room1/temp但sensor/#/temp是无效语法注意#只能出现在最后。QoS传递逻辑发布QoS为0即使订阅端请求QoS 2最多收到QoS 0消息发布QoS 2、订阅QoS 1时消息按QoS 1投递。两边协商取最小值。认证权限确保订阅账号具有订阅该主题的权限有些认证配置了ACL但忘记给新账号加读写权限。其中第4点是原理性知识最容易忽略但每次都让人抓狂。建议在测试阶段固定发布端和订阅端都是QoS 1避免混用引起的“伪丢消息”现象。6.3 我的几条独家避坑经验经验一日志要会看两个地方EMQX出问题时第一现场在/var/log/emqx/emqx.log第二现场是Dashboard的“监控”页面。日志级别默认是warning如果怀疑数据层面有问题可以在配置文件里临时把日志级别调成debug排查完再改回来。调日志对性能有一定影响生产环境谨慎操作。经验二升级版本前先备份数据目录EMQX配置和用户数据都在/opt/emqx/data下。升级前先tar czf emqx-data.tar.gz /opt/emqx/data升级后如果Dashboard里的用户不见了直接用备份恢复整个目录。血的教训别问怎么知道的。经验三不要用默认密码跑生产EMQX安装后默认账号密码是admin/public很多人装完顺手改一下Dashboard密码就觉得万事大吉。实际上MQTT客户端这一层是一个独立的认证体系Dashboard的管理员密码只保护网页控制台设备连接是用认证里创建的用户名密码两层一定要分别设置强度足够的密码。经验四时间不同步先修时钟EMQX的TLS证书校验和遗嘱消息都依赖系统时间。遇到莫名其妙连接失败、证书报错先执行date看系统时间是否准确。Ubuntu服务器默认可能没装NTP建议一开始就同步好sudo apt install -y ntpdate sudo ntpdate ntp.aliyun.com经验五日志别存根目录EMQX默认日志存储位置是/opt/emqx/log运行时间长了日志增长很快。建议做日志轮转限制或者在磁盘规划时为/opt单独分区。不然日志写满根分区整个系统都会出现各种诡异问题这是运维阶段最容易炸掉的雷。在Ubuntu 20.04上搭建EMQX整体流程比我预想的顺滑从装环境到跑通订阅发布一个下午就能完成。最花时间的部分是理解MQTT的订阅和发布模型以及认证配置的逻辑。把这套基础打牢后后面接设备、做规则引擎、对接数据平台都是在现有框架上添加能力的环节踩坑概率大大降低。如果只是个人学习和设备量不大的场景社区版EMQX配合这笔记里的配置完全够用等后面设备量超过千台再考虑集群方案也不迟。