Docker部署EMQX企业版:MQTT物联网消息中间件实践
1. 项目概述:MQTT与EMQX的核心价值
MQTT(Message Queuing Telemetry Transport)作为轻量级的物联网通信协议,已经成为设备互联的事实标准。其发布/订阅模式、低带宽消耗和QoS分级等特性,特别适合物联网场景下的设备通信。而EMQX作为开源企业级MQTT消息中间件,凭借其高并发连接处理能力(单节点支持500万连接)和毫秒级消息转发延迟,在车联网、工业物联网等领域广泛应用。
本次搭建将基于Docker环境部署EMQX 6.2.2企业版,相比社区版,企业版提供了更完善的数据集成、规则引擎和集群管理功能。选择Docker部署方式主要基于三点考虑:
- 环境隔离性:避免与宿主机环境产生依赖冲突
- 部署便捷性:官方镜像已包含所有运行时依赖
- 可移植性:方便后续迁移到Kubernetes等编排系统
2. 环境准备与基础部署
2.1 Docker环境配置建议
在开始前,建议对Docker环境进行以下优化配置(以Ubuntu 22.04为例):
# 调整Docker日志驱动和存储限制 sudo tee /etc/docker/daemon.json <<EOF { "log-driver": "json-file", "log-opts": {"max-size": "10m", "max-file": "3"}, "storage-driver": "overlay2", "storage-opts": ["size=50GB"] } EOF # 应用配置并重启服务 sudo systemctl restart docker注意:生产环境建议单独挂载数据盘到/var/lib/docker目录,避免系统盘空间耗尽
2.2 单节点部署实操
通过以下命令获取并运行EMQX镜像:
# 拉取指定版本镜像(国内用户可添加--registry-mirror参数加速) docker pull emqx/emqx-enterprise:6.2.2 # 运行容器(建议使用host网络模式提升性能) docker run -d \ --name emqx \ --hostname emqx-node1 \ --network host \ -e "EMQX_NODE_NAME=emqx@node1.emqx.com" \ -v /data/emqx/data:/opt/emqx/data \ -v /data/emqx/log:/opt/emqx/log \ emqx/emqx-enterprise:6.2.2关键参数说明:
--network host:使用主机网络模式,避免NAT带来的性能损耗- 挂载卷包含:
- /opt/emqx/data:持久化Mnesia数据库(存储订阅关系等)
- /opt/emqx/log:日志文件存储
- 环境变量:
- EMQX_NODE_NAME:节点命名格式必须为
emqx@hostname
- EMQX_NODE_NAME:节点命名格式必须为
验证服务状态:
docker exec -it emqx emqx_ctl status正常应返回"Node emqx@node1.emqx.com is started"
3. 集群化部署方案
3.1 静态集群配置
对于生产环境,建议使用3-5节点组成集群保证高可用。以下是docker-compose.yml示例:
version: '3' services: emqx1: image: emqx/emqx-enterprise:6.2.2 hostname: node1.emqx.com environment: EMQX_NODE_NAME: emqx@node1.emqx.com EMQX_CLUSTER__DISCOVERY_STRATEGY: static EMQX_CLUSTER__STATIC__SEEDS: "emqx@node1.emqx.com,emqx@node2.emqx.com" networks: emqx-net: ipv4_address: 172.22.1.10 volumes: - ./node1_data:/opt/emqx/data emqx2: image: emqx/emqx-enterprise:6.2.2 hostname: node2.emqx.com environment: EMQX_NODE_NAME: emqx@node2.emqx.com EMQX_CLUSTER__DISCOVERY_STRATEGY: static EMQX_CLUSTER__STATIC__SEEDS: "emqx@node1.emqx.com,emqx@node2.emqx.com" networks: emqx-net: ipv4_address: 172.22.1.11 volumes: - ./node2_data:/opt/emqx/data networks: emqx-net: driver: bridge ipam: config: - subnet: 172.22.1.0/24启动集群:
docker-compose up -d docker exec -it emqx1 emqx_ctl cluster status3.2 网络调优建议
对于跨主机的集群通信,需要调整内核参数:
# 调整TCP缓冲区大小 echo 'net.core.rmem_default=262144' >> /etc/sysctl.conf echo 'net.core.wmem_default=262144' >> /etc/sysctl.conf echo 'net.ipv4.tcp_keepalive_time=600' >> /etc/sysctl.conf # EMQX特定优化 echo 'net.ipv4.tcp_max_syn_backlog=10240' >> /etc/sysctl.conf echo 'fs.file-max = 2097152' >> /etc/sysctl.conf sysctl -p4. 安全配置实践
4.1 基础认证配置
修改etc/plugins/emqx_auth_mnesia.conf:
# 密码加密方式 auth.mnesia.password_hash = sha256 # 默认用户(启动后应立即修改) auth.user.1.username = admin auth.user.1.password = public auth.user.1.is_superuser = true通过REST API创建新用户:
curl -X POST -u admin:public \ -H "Content-Type: application/json" \ -d '{"username":"iot_user", "password":"Str0ngP@ss", "is_superuser":false}' \ http://127.0.0.1:18083/api/v5/authentication/password_based:built_in_database/users4.2 TLS加密配置
生成自签名证书:
openssl req -x509 -newkey rsa:4096 \ -keyout key.pem -out cert.pem \ -days 365 -nodes -subj "/CN=emqx.example.com"配置etc/emqx.conf:
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" } }5. 客户端连接测试
5.1 使用MQTTX工具测试
安装MQTTX客户端:
wget https://github.com/emqx/MQTTX/releases/download/v1.9.3/mqttx-1.9.3.AppImage chmod +x mqttx-1.9.3.AppImage连接参数示例:
- 地址:emqx.example.com
- 端口:1883(非加密)/8883(SSL)
- 用户名/密码:iot_user/Str0ngP@ss
5.2 压力测试方法
使用emqtt-bench工具:
docker run -it --rm emqx/emqtt-bench \ conn -h emqx.example.com -p 1883 -u iot_user -P Str0ngP@ss -c 5000 -i 10参数说明:
- -c 5000:模拟5000个并发连接
- -i 10:每隔10秒建立一个新连接
6. 运维监控方案
6.1 Prometheus监控配置
启用Prometheus插件:
docker exec -it emqx emqx_ctl plugins load emqx_prometheus配置etc/plugins/emqx_prometheus.conf:
prometheus.export.interval = 15 prometheus.push_gateway.server = "http://prometheus:9091"6.2 关键监控指标
| 指标名称 | 说明 | 告警阈值 |
|---|---|---|
| emqx_connections_count | 当前连接数 | > 80%最大连接数 |
| emqx_messages_received | 每分钟接收消息数 | 突增300% |
| emqx_deliver_duration | 消息投递延迟(ms) | P99 > 500ms |
| emqx_system_memory_used | 内存使用率 | > 85% |
7. 常见问题排查
7.1 连接失败排查流程
检查防火墙规则:
iptables -L -n | grep 1883验证端口监听状态:
docker exec -it emqx netstat -tulnp | grep 1883查看客户端错误日志:
docker logs --since 5m emqx | grep -i auth
7.2 性能问题优化
典型性能瓶颈及解决方案:
CPU高负载:
- 调整
etc/emqx.conf中的listener.tcp.external.acceptors - 增加
vm.args中的+S参数(如+S 4:4表示4个调度器)
- 调整
内存增长过快:
# 限制容器内存 docker update --memory 2G --memory-swap 4G emqx消息堆积:
- 调整
persistent_session_store的max_retain_seconds - 启用
delayed插件处理延迟消息
- 调整
8. 生产环境建议
经过多年实践,总结出以下经验要点:
存储规划:
- 使用SSD存储Mnesia数据
- 预留5倍消息量的磁盘空间
- 定期清理
data/mnesia/*中的旧数据
集群部署:
- 奇数节点数量(3/5/7)
- 跨可用区部署
- 使用专有网络避免公网通信
版本升级:
# 蓝绿升级步骤 docker-compose -f docker-compose-new.yml up -d docker-compose -f docker-compose-old.yml stop备份策略:
# 每日定时备份配置和数据 tar czvf emqx-bak-$(date +%F).tar.gz \ /data/emqx/data /data/emqx/etc
实际部署中曾遇到过一个典型案例:某客户在高峰期出现连接抖动,最终发现是默认的TCP缓冲区大小不足导致。通过调整net.ipv4.tcp_mem和net.core.rmem_max参数后,连接稳定性得到显著改善。这提醒我们,MQTT服务的稳定运行不仅取决于软件配置,更需要系统级的调优配合。