EMQX是一款高性能、可扩展的开源MQTT消息服务器,广泛应用于物联网、微服务等场景。本文将基于Ubuntu系统,结合Docker Compose实现EMQX集群的快速部署,针对中国网络环境优化镜像拉取策略,同时覆盖集群配置、验证及常见问题排查,适合Java后端开发、DevOps工程师及物联网运维人员参考。
一、环境准备
1.1 系统要求
-
操作系统:Ubuntu 22.04.5 LTS(64位)
-
Docker版本:Docker version 28.0.4
-
Docker Compose版本:v2.34.0
-
硬件配置:最低2核4G内存(集群节点建议每节点2核4G及以上)
-
网络要求:集群节点间网络互通(默认需开放1883、8083、8084、18083、4370、5369端口)
1.2 IP地址
- 节点1:172.28.0.10
- 节点2:172.28.0.11
1.3 Docker 和 Docker compose 安装
参考:Ubuntu22.04 安装 Docker 及 Docker Compose v2 详细教程
二、EMQX集群部署核心配置
EMQX集群支持多种发现方式,本文采用static静态发现(适合固定节点IP场景),同时配置持久化存储、自定义账号密码及网络优化。
2.1 创建部署目录结构
bash
# 创建EMQX部署根目录
mkdir -p /opt/emqx-cluster
cd /opt/emqx-cluster
# 创建节点数据存储目录(每个节点独立目录,避免数据冲突)
mkdir -p data/node1 data/node2
sudo chmod 777 -R data/ # 赋予权限,避免容器读写权限问题
2.2 编写docker-compose.yml文件
创建docker-compose.yml文件,定义2个节点的EMQX集群(可根据需求扩展节点数量),使用EMQX官方镜像(国内可通过阿里云镜像仓库拉取)。
- 节点1
yaml
services:
emqx:
# 指定 EMQX 镜像版本
image: emqx/emqx:5.6.1
# 容器名称
container_name: emqx_cluster
environment:
- EMQX_NODE_NAME=emqx@172.28.0.10 #节点名称,格式:emqx@服务器IP
- EMQX_NODE__COOKIE=emqx_cluster_cookie_2026 # EMQX 节点通信密钥
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static # 基于 static 节点列表自动集群
- EMQX_CLUSTER__STATIC__SEEDS=[emqx@10.0.0.128,emqx@172.28.0.10] # 集群所有节点列表
- EMQX_DASHBOARD__DEFAULT_USERNAME=admin # 制台默认用户名
- EMQX_DASHBOARD__DEFAULT_PASSWORD=emqx123456 # 制台默认密码
ports:
- 1883:1883 # TCP端口
- 8083:8083 # WebSocket端口
- 8084:8084 # 安全 WebSocket(WSS)端口
- 8883:8883 # SSL端口
- 18083:18083 # 控制台端口
- 4370:4370 # Erlang 分布式传输端口
- 5369:5369 # 集群 RPC 端口
restart: always
volumes:
- ./data:/opt/emqx/data
- ./log:/opt/emqx/log
- 节点2
yaml
services:
emqx:
# 指定 EMQX 镜像版本
image: emqx/emqx:5.6.1
# 容器名称
container_name: emqx_cluster
environment:
- EMQX_NODE_NAME=emqx@172.28.0.11 #节点名称,格式:emqx@服务器IP
- EMQX_NODE__COOKIE=emqx_cluster_cookie_2026 # EMQX 节点通信密钥
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static # 基于 static 节点列表自动集群
- EMQX_CLUSTER__STATIC__SEEDS=[emqx@10.0.0.128,emqx@172.28.0.11] # 集群所有节点列表
- EMQX_DASHBOARD__DEFAULT_USERNAME=admin # 制台默认用户名
- EMQX_DASHBOARD__DEFAULT_PASSWORD=emqx123456 # 制台默认密码
ports:
- 1883:1883 # TCP端口
- 8083:8083 # WebSocket端口
- 8084:8084 # 安全 WebSocket(WSS)端口
- 8883:8883 # SSL端口
- 18083:18083 # 控制台端口
- 4370:4370 # Erlang 分布式传输端口
- 5369:5369 # 集群 RPC 端口
restart: always
volumes:
- ./data:/opt/emqx/data
- ./log:/opt/emqx/log
核心配置说明
-
集群Cookie :
EMQX_NODE_COOKIE是集群节点间通信的认证密钥,所有节点必须完全一致,否则无法加入集群。 -
节点名称 :格式为
节点名@IP,IP需使用集群内网固定IP,避免使用localhost或127.0.0.1。 -
端口映射:多个节点映射到宿主机的端口需不同,避免端口冲突;核心端口功能:
-
1883:MQTT协议默认TCP端口,用于设备连接。
-
8083:MQTT WebSocket端口,用于浏览器端连接。
-
18083:Web管理控制台端口,用于集群运维。
-
4370/5369:集群内部通信端口
-
-
持久化存储:通过挂载宿主机目录保存EMQX数据和日志,避免容器删除后数据丢失,适合生产环境。
三、启动EMQX集群
3.1 拉取镜像并启动集群
bash
# 进入部署目录
cd /opt/emqx-cluster
# 拉取镜像并启动集群(-d参数后台运行)
docker-compose up -d
# 查看容器启动状态
docker-compose ps
# 查看集群启动日志(若启动失败,可通过日志排查问题)
docker-compose logs -f # 实时查看所有节点日志
docker logs -f emqx1 # 单独查看节点1日志
3.2 启动成功验证
若启动成功,docker-compose ps命令输出中,两个节点的状态均为Up。此时可通过两种方式验证集群状态:
3.2.1 命令行验证集群状态
bash
# 进入节点1服务器对应的emqx容器内部
docker exec -it emqx /bin/bash
# 查看集群状态
emqx_ctl cluster status
# 预期输出(表示两个节点已成功组成集群):
Cluster status: #{running_nodes => ['emqx@172.28.0.10','emqx@10.0.0.128'],
stopped_nodes => []}
3.2.2 Web控制台验证
-
打开浏览器,访问宿主机IP:18083(节点1控制台)或宿主机IP:18084(节点2控制台)。

-
使用配置文件中定义的账号(admin)和密码(emqx123456)登录。
-
登录后,点击左侧菜单栏「集群」,可查看集群节点列表、节点状态、负载情况等信息,确认两个节点均处于「运行中」状态。


四、集群核心功能配置(可选)
4.1 自定义MQTT监听端口
若需修改MQTT默认端口,可在environment中添加以下配置(以节点1为例):
yaml
environment:
- EMQX_LISTENER__TCP__DEFAULT__BIND=1885 # 将TCP端口改为1885
- EMQX_LISTENER__WS__DEFAULT__BIND=8086 # 将WebSocket端口改为8086
修改后需重启集群:docker-compose down && docker-compose up -d。
4.2 配置访问控制(ACL)
通过挂载ACL文件限制设备访问权限,在宿主机创建acl.conf文件:
bash
# 创建ACL配置文件
touch /opt/emqx-cluster/acl.conf
# 编辑ACL规则(示例:允许admin用户订阅所有主题,禁止匿名用户发布消息)
cat > /opt/emqx-cluster/acl.conf <<-'EOF'
## 允许admin用户订阅所有主题
{allow, {user, "admin"}, subscribe, ["#"]}.
## 禁止匿名用户发布消息
{deny, all, publish, ["#"]}.
## 允许所有用户订阅自己的主题
{allow, all, subscribe, ["${clientid}/#"]}.
EOF
在docker-compose.yml中添加挂载配置(每个节点均需添加):
yaml
volumes:
- ./acl.conf:/opt/emqx/etc/acl.conf
重启集群使配置生效:docker-compose restart。
4.3 配置数据持久化(进阶)
默认情况下,EMQX数据存储在宿主机挂载目录,若需更高可靠性,可结合NFS或分布式存储挂载,确保集群节点数据一致性。
五、常见问题排查(Ubuntu环境专属)
5.1 集群节点无法加入
问题现象 :emqx_ctl cluster status显示只有单个节点,另一个节点处于stopped状态。
解决方案:
-
检查所有节点的
EMQX_NODE_COOKIE是否完全一致,不一致会导致认证失败。 -
确认集群网络互通:进入容器内部ping其他节点IP(如
ping 172.28.0.11),若无法ping通,检查宿主机防火墙是否放行172.28.0.0/16网段。
# 开放集群网段防火墙规则 sudo ufw allow from 172.28.0.0/16 sudo ufw reload -
手动将节点加入集群:
`# 进入节点2容器
docker exec -it emqx /bin/bash
手动加入emqx1节点
emqx_ctl cluster join emqx1@172.28.0.10
再次查看集群状态
emqx_ctl cluster status`
5.2 宿主机无法访问Web控制台
问题现象:浏览器访问宿主机IP:18083时无法打开页面。
解决方案:
-
检查容器端口映射是否正确:
docker-compose ps确认18083端口已映射到宿主机。 -
开放宿主机防火墙端口:
sudo ufw allow 18083/tcp sudo ufw allow 18084/tcp sudo ufw reload -
检查容器内部控制台是否正常运行:
docker exec -it emqx1 emqx_ctl status # 确认EMQX服务正常运行 netstat -tnlp | grep 18083 # 确认容器内18083端口已监听
5.3 数据持久化失败
问题现象:容器重启后,之前创建的用户、规则等数据丢失。
解决方案:
-
检查宿主机挂载目录权限:确保
/opt/emqx-cluster/data目录权限为777(sudo chmod 777 -R /opt/emqx-cluster/data)。 -
确认挂载路径正确:docker-compose.yml中volumes配置的宿主机路径与容器路径对应无误。
-
查看容器日志排查权限问题:
docker logs -f emqx1 | grep permission,根据日志提示调整权限。
六、集群运维与扩展
6.1 集群重启与停止
bash
# 重启集群
docker-compose restart
# 停止集群(保留容器和数据)
docker-compose stop
# 停止并删除容器(数据仍保留在宿主机)
docker-compose down
# 停止并删除容器及镜像
docker-compose down --rmi all
6.2 节点扩容(新增节点3)
-
在docker-compose.yml中添加节点3配置,参考节点2的格式,修改IP(如172.28.0.12)、容器名、端口映射。
-
创建节点3数据目录:
mkdir -p /opt/emqx-cluster/data/node3 && sudo chmod 777 -R data/node3。 -
更新集群配置:所有节点的
EMQX_CLUSTER__STATIC__SEEDS添加新节点(emqx3@172.28.0.12)。 -
启动新节点:
docker-compose up -d emqx3。 -
验证扩容结果:
docker exec -it emqx1 emqx_ctl cluster status,确认新节点已加入集群。
6.3 日志分析与监控
EMQX日志默认存储在宿主机/opt/emqx-cluster/data/node1/log和node2/log目录,核心日志文件:
-
emqx.log:主日志文件,记录集群运行状态、错误信息等。 -
access.log:访问日志,记录设备连接、消息收发等请求。
生产环境可结合ELK、Prometheus+Grafana等工具实现日志集中管理和性能监控。
七、生产环境优化建议
-
网络优化:集群节点建议部署在同一局域网,避免跨网段通信导致延迟;开启MQTT over QUIC协议(8084端口),提升弱网环境下的连接稳定性。
-
资源限制:在docker-compose.yml中为每个节点添加资源限制,避免单个节点占用过多资源,示例:
yaml
deploy:
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2G`
-
高可用配置:结合Keepalived实现宿主机IP漂移,避免单节点故障导致服务中断;使用负载均衡器(如Nginx、HAProxy)分发MQTT连接请求到集群节点。
-
安全加固 :修改默认账号密码为复杂密码;关闭匿名访问(
EMQX_ALLOW_ANONYMOUS=false);开启TLS/SSL加密(配置证书文件,启用8883端口)。
八、总结
本文基于Ubuntu环境,通过Docker Compose实现了EMQX集群的快速部署,覆盖了环境准备、配置编写、集群启动、验证运维及常见问题排查,同时针对中国网络环境优化了镜像拉取策略。EMQX集群可有效提升MQTT消息服务的并发处理能力和可用性,适合物联网大规模设备接入场景。后续可根据实际业务需求,扩展集群节点数量、优化访问控制策略及监控方案。