从零到一:手把手搭建高可用EMQX MQTT服务器

张开发
2026/4/25 4:44:21 15 分钟阅读

分享文章

从零到一:手把手搭建高可用EMQX MQTT服务器
1. EMQX简介与核心概念MQTT协议作为物联网领域的普通话已经成为设备互联的事实标准。而EMQX则是目前最流行的开源MQTT消息中间件之一就像物联网世界的交通枢纽。我最早接触EMQX是在2018年一个智能家居项目中当时为了处理数万设备的并发连接尝试了多种方案后最终选择了它。EMQX的核心优势在于其分布式架构和百万级连接处理能力。最新版本5.x相比早期版本在性能上有质的飞跃——在我的压力测试中单节点轻松支撑10万的MQTT连接。对于开发者而言它提供了开箱即用的管理控制台让消息流转和设备管理变得可视化。这里有个生活化的类比想象EMQX就像快递公司的分拣中心。设备客户端把包裹消息送到分拣中心EMQX服务器由服务器根据地址Topic主题准确投递给收件人订阅者。而MQTT协议就是快递员之间的暗号保证包裹高效无误地传递。2. 环境准备与安装2.1 硬件与系统要求在实际部署中资源配置需要根据业务规模灵活调整。对于开发测试环境我通常这样配置云服务器2核4G配置阿里云ECS t6系列就够用操作系统Ubuntu 20.04 LTS长期支持版更稳定磁盘空间至少50GB消息持久化需要额外空间注意生产环境建议使用物理机或高性能云主机避免虚拟化带来的性能损耗2.2 安装方式对比EMQX提供多种安装方式这里我推荐两种最常用的二进制包安装适合快速体验wget https://www.emqx.com/zh/downloads/broker/5.0.20/emqx-5.0.20-ubuntu20.04-amd64.tar.gz tar -zxvf emqx-5.0.20-ubuntu20.04-amd64.tar.gz cd emqx/bin ./emqx startDocker安装适合容器化部署docker run -d --name emqx \ -p 1883:1883 -p 8083:8083 \ -p 8084:8084 -p 8883:8883 \ -p 18083:18083 \ emqx/emqx:5.0.20我在AWS上实测发现Docker方式会损失约15%的性能但部署灵活性更高。如果追求极致性能建议直接使用二进制安装。3. 基础配置与安全加固3.1 必须做的安全设置第一次启动后立即访问http://服务器IP:18083会看到登录界面。使用默认账号admin/public登录后第一件事就是修改密码我见过太多因为没改密码导致的安全事故。通过CLI修改密码的方法适合批量部署./emqx_ctl admins passwd admin 你的新密码3.2 网络端口配置EMQX默认开放的端口需要特别注意1883MQTT协议标准端口8883MQTT over SSL8083WebSocket连接8084WSS(WebSocket Secure)生产环境中我强烈建议关闭不必要的端口如8083为8883端口配置有效的SSL证书使用防火墙限制访问源IP配置SSL的示例需要提前准备证书listeners.ssl.default { bind 0.0.0.0:8883 max_connections 102400 ssl_options { keyfile /etc/emqx/certs/key.pem certfile /etc/emqx/certs/cert.pem cacertfile /etc/emqx/certs/cacert.pem } }4. 高可用集群搭建4.1 集群架构设计EMQX集群采用去中心化架构各节点平等。在我的生产实践中通常采用3节点或5节点部署。下图展示了一个典型的三节点部署方案[客户端] | [负载均衡器] | [EMQX Node1] ↔ [EMQX Node2] ↔ [EMQX Node3] | | | [Redis集群] [MySQL集群] [监控系统]4.2 具体搭建步骤假设有三台服务器192.168.1.10、192.168.1.11、192.168.1.12首先确保各节点时间同步NTP服务修改每台服务器的/etc/hosts文件添加主机名解析在第一台节点执行./emqx start ./emqx_ctl cluster join emqx192.168.1.11验证集群状态./emqx_ctl cluster status踩坑提醒我曾遇到集群节点无法发现的问题后来发现是防火墙没放行4370端口。建议提前检查端口连通性。5. 性能调优实战5.1 关键参数调整在/etc/emqx/emqx.conf中这几个参数直接影响性能# 最大连接数根据内存调整 zone.external.max_connections 1000000 # 消息吞吐量优化 listener.tcp.external.rate_limit 1000,10000 # 会话超时设置 zone.external.session_expiry_interval 2h5.2 监控与告警EMQX内置了Prometheus监控接口地址为http://IP:18083/api/v5/prometheus/stats。我通常配合Grafana使用这个看板配置dashboard { ## Prometheus Dashboard URL prometheus http://localhost:3000/d/emqx/emqx-prometheus-dashboard?orgId1 ## AlertManager URL alertmanager http://localhost:9093 }常见性能瓶颈排查经验连接数上不去 → 检查ulimit和TCP参数消息延迟高 → 检查网络带宽和磁盘IOCPU跑满 → 检查是否有异常主题订阅6. 客户端开发实践6.1 Python连接示例使用paho-mqtt库的完整示例import paho.mqtt.client as mqtt def on_connect(client, userdata, flags, rc): print(Connected with result code str(rc)) client.subscribe(test/topic) def on_message(client, userdata, msg): print(msg.topic str(msg.payload)) client mqtt.Client() client.on_connect on_connect client.on_message on_message client.connect(your_server_ip, 1883, 60) client.loop_forever()6.2 生产环境注意事项必须实现断线重连物联网设备网络环境复杂合理设置QoS级别QoS0可能丢失适合传感器数据QoS1至少一次适合控制指令QoS2精确一次适合支付场景客户端ID规范建议使用设备类型MAC地址的格式7. 常见问题解决方案问题1Dashboard无法访问检查防火墙规则确认EMQX是否正常运行./emqx_ctl status查看日志/var/log/emqx/emqx.log.1问题2客户端连接频繁断开# 调整keepalive参数 listener.tcp.external.keepalive 3600s问题3高并发下消息丢失# 优化消息队列设置 zone.external.max_mqueue_len 10000 zone.external.mqueue_priorities none记得第一次上线时遇到消息堆积问题后来发现是默认队列长度太小。调整后稳定运行至今。EMQX的灵活性就在于这些参数都可以根据业务特点精细调整。

更多文章