4、搭建 MQTT Broker:Mosquitto 与 EMQX 实战
好,咱们进入第四章。前面几章我们把 MQTT 协议的原理、报文结构都捋了一遍,算是把“车”的构造搞清楚了。但车要跑起来,得有条路,这条路就是 Broker(代理服务器)。
说白了,Broker 就是 MQTT 通信的“路由器”。所有设备都连到它身上,它负责收消息、转发消息、管理连接。没有 Broker,设备之间就是孤岛。
这一章,我带你亲手搭建两个最主流的 Broker:Mosquitto 和 EMQX。一个轻量经典,一个高性能集群。最后再给它们加上安全锁——用户名密码和 ACL 权限控制。
- 掌握 Mosquitto 的安装、配置与基础运维
- 掌握 EMQX 的安装、Dashboard 管理与集群概念
- 学会配置用户名密码认证
- 学会配置 ACL 访问控制列表
4.1 Mosquitto:轻量级 Broker 的经典之选
Mosquitto 是 Eclipse 基金会下的开源项目,用 C 语言写的,体积小、资源占用低。我个人习惯在树莓派或者低配的 Linux 服务器上用它,跑个几年都不带重启的。
4.1.1 安装 Mosquitto
在 Ubuntu/Debian 上,安装非常简单:
# 更新包索引
sudo apt update
# 安装 Mosquitto 和客户端工具
sudo apt install -y mosquitto mosquitto-clients
# 检查服务状态
sudo systemctl status mosquitto
安装完成后,Mosquitto 默认就已经在后台运行了。监听 1883 端口(非加密 MQTT)和 8883 端口(加密 MQTT,需要证书)。
yum install -y mosquitto。不过 EPEL 源要提前配好。
4.1.2 核心配置文件:mosquitto.conf
配置文件默认在 /etc/mosquitto/mosquitto.conf。我建议你直接编辑它,而不是用默认配置。下面是一个我常用的最小化配置:
# 监听端口
listener 1883
# 允许匿名访问(后续我们会关掉)
allow_anonymous true
# 持久化消息存储
persistence true
persistence_location /var/lib/mosquitto/
# 日志
log_dest file /var/log/mosquitto/mosquitto.log
log_type all
改完配置后,重启服务:
sudo systemctl restart mosquitto
4.1.3 快速测试
用两个终端窗口,一个订阅,一个发布:
# 终端1:订阅 test/topic
mosquitto_sub -h localhost -t "test/topic" -v
# 终端2:发布消息
mosquitto_pub -h localhost -t "test/topic" -m "Hello, MQTT!"
如果终端1收到了消息,说明 Broker 跑起来了。嗯,就是这么简单。
allow_anonymous true)。这在生产环境是绝对不行的!我们后面会把它关掉。
4.2 EMQX:高性能分布式 Broker
EMQX 是用 Erlang/OTP 写的,天生就支持高并发和集群。我在一个百万级设备的物联网项目中用过它,单机就能扛住几十万连接,非常稳。
4.2.1 安装 EMQX
EMQX 提供了多种安装方式。我推荐用 Docker 或者直接下载二进制包。这里用 Docker 演示:
# 拉取 EMQX 最新版
docker pull emqx/emqx:latest
# 启动 EMQX
docker run -d --name emqx \
-p 1883:1883 \
-p 8083:8083 \
-p 8084:8084 \
-p 18083:18083 \
emqx/emqx:latest
端口说明:
| 端口 | 用途 |
|---|---|
| 1883 | MQTT 非加密端口 |
| 8083 | MQTT over WebSocket(非加密) |
| 8084 | MQTT over WebSocket(加密) |
| 18083 | Dashboard 管理界面(HTTP) |
启动后,浏览器访问 http://localhost:18083,默认用户名 admin,密码 public。进去后第一件事就是改密码,别问我为什么知道……
4.2.2 Dashboard 管理
EMQX 的 Dashboard 做得非常直观。你可以在这里看到:
- 当前连接数、消息吞吐量
- 订阅关系、主题统计
- 客户端列表、会话状态
- 集群节点状态(如果是集群模式)
我个人觉得,对于中小团队,EMQX 的 Dashboard 已经能替代大部分监控工具了。
4.3 Broker 安全设置:别让 Broker 裸奔
好,Broker 跑起来了,但现在是“裸奔”状态——谁都能连,谁都能发消息。这就像你家大门敞开,谁都能进来坐坐。我曾经在一个客户现场发现,他们的 Mosquitto 居然允许匿名连接,结果被恶意设备灌了上亿条垃圾消息,直接把服务器搞挂了。从那以后,我每次搭建 Broker,第一件事就是关匿名、加认证。
4.3.1 用户名密码认证
Mosquitto 配置密码认证
第一步:创建密码文件
# 创建密码文件,添加用户 device1
sudo mosquitto_passwd -c /etc/mosquitto/passwd device1
# 输入密码两次
# 添加更多用户
sudo mosquitto_passwd /etc/mosquitto/passwd device2
第二步:修改 mosquitto.conf
# 关闭匿名访问
allow_anonymous false
# 启用密码文件认证
password_file /etc/mosquitto/passwd
第三步:重启 Mosquitto
sudo systemctl restart mosquitto
现在再测试,不加用户名密码就连接不上了:
# 这个会失败
mosquitto_sub -h localhost -t "test/topic"
# 这个才能成功
mosquitto_sub -h localhost -t "test/topic" -u device1 -P yourpassword
EMQX 配置密码认证
EMQX 的认证配置在 Dashboard 里就能搞定:
- 登录 Dashboard,进入“管理” -> “认证”
- 选择“内置数据库”作为认证后端
- 添加用户:输入用户名、密码
- 保存并启用
或者通过 API 添加:
curl -X POST http://localhost:18083/api/v5/authentication/password_based:built_in_database/users \
-H "Content-Type: application/json" \
-d '{"user_id": "device1", "password": "securepass123"}'
4.3.2 ACL 访问控制:精细化管理
光有用户名密码还不够。你想想看,如果 device1 能订阅 device2 的私有主题,那数据就泄露了。ACL(Access Control List)就是用来解决这个问题的——它控制每个用户能发布/订阅哪些主题。
Mosquitto ACL 配置
第一步:创建 ACL 文件 /etc/mosquitto/acl
# 允许 device1 发布和订阅 sensor/temperature
user device1
topic write sensor/temperature
topic read sensor/temperature
# 允许 device2 订阅 sensor/#
user device2
topic read sensor/#
# 拒绝所有其他操作(默认规则)
topic deny #
第二步:在 mosquitto.conf 中启用 ACL
acl_file /etc/mosquitto/acl
第三步:重启 Mosquitto
sudo systemctl restart mosquitto
现在,device1 只能操作 sensor/temperature,而 device2 可以读取所有 sensor/ 开头的主题。如果 device1 想订阅 sensor/humidity,会被直接拒绝。
topic deny #。结果 Mosquitto 默认允许所有未明确拒绝的操作,等于 ACL 没生效。记住:ACL 的默认行为是“允许”,所以一定要显式拒绝。
EMQX ACL 配置
EMQX 的 ACL 同样可以在 Dashboard 里配置:
- 进入“管理” -> “授权”
- 选择“内置数据库”
- 添加规则:指定用户、主题、操作(发布/订阅)、允许/拒绝
例如,添加一条规则:
- 用户:device1
- 主题:sensor/temperature
- 操作:发布 + 订阅
- 动作:允许
EMQX 的 ACL 支持通配符,也支持按客户端 ID 或 IP 地址做限制,非常灵活。
4.4 本章小结
这一章我们干了三件事:
- 装了 Mosquitto 和 EMQX 两个 Broker
- 配置了基础参数,让它们跑起来
- 加了安全锁——用户名密码认证和 ACL 权限控制
现在你的 Broker 已经不是“裸奔”状态了。设备连接需要身份,操作主题需要权限。这才是生产环境该有的样子。