搞物联网开发的朋友肯定绕不开 MQTT 这个协议。今天我们来聊聊怎么自建一个靠谱的 MQTT 代理服务器,用 Eclipse Mosquitto 这个开源方案。
为什么要自建?公共 MQTT 服务器虽然方便,但数据安全没保障,连接稳定性也看人家心情。自己搭建的话,数据完全掌控,还能根据需求定制优化。
需要准备什么?
| 物品 | 型号/规格 | 价格 |
|---|---|---|
| 服务器 | 树莓派 4B / 云服务器 | ¥350-500 |
| 或 | 旧笔记本/台式机 | ¥0 (利旧) |
| 存储 | 16GB SD 卡 / SSD | ¥30-200 |
| 网络 | 有线网络优先 | ¥0 |
| 域名 | 可选 (用于外网访问) | ¥50/年 |
| 总计 | ¥80-750 |
我用的是家里闲置的树莓派 4B,24 小时开机功耗也就 5W 左右,一年电费不到 30 块钱,香!
步骤 1:安装 Mosquitto
Ubuntu/Debian 系统
# 更新软件源
sudo apt-get update
# 安装 Mosquitto 和客户端工具
sudo apt-get install -y mosquitto mosquitto-clients
# 查看服务状态
systemctl status mosquitto
Fedora/CentOS 系统
# 启用 EPEL 源
sudo dnf install -y epel-release
# 安装 Mosquitto
sudo dnf install -y mosquitto mosquitto-clients
# 启动服务
sudo systemctl enable mosquitto
sudo systemctl start mosquitto
Docker 方式 (推荐)
如果你已经熟悉 Docker,这种方式最干净:
docker run -d \
--name mosquitto \
--restart always \
-p 1883:1883 \
-p 9001:9001 \
-v /opt/mosquitto/config:/mosquitto/config \
-v /opt/mosquitto/data:/mosquitto/data \
-v /opt/mosquitto/log:/mosquitto/log \
eclipse-mosquitto:latest
注意事项: ⚠️ 默认安装后 Mosquitto 是允许匿名连接的,生产环境一定要配置认证!
步骤 2:基础配置
配置文件位置:/etc/mosquitto/mosquitto.conf
最小安全配置
# 备份原配置
sudo cp /etc/mosquitto/mosquitto.conf /etc/mosquitto/mosquitto.conf.bak
# 创建配置文件
sudo nano /etc/mosquitto/mosquitto.conf
填入以下内容:
# 监听端口
listener 1883
listener 9001
protocol websockets
# 禁止匿名连接
allow_anonymous false
# 密码文件路径
password_file /etc/mosquitto/passwd
# 持久化设置
persistence true
persistence_location /var/lib/mosquitto/
# 日志配置
log_dest file /var/log/mosquitto/mosquitto.log
log_type error
log_type warning
log_type notice
log_type information
# 连接限制
max_connections 1000
max_queued_messages 100
创建用户密码
# 创建密码文件 (第一个用户用 -c 参数)
sudo mosquitto_passwd -c /etc/mosquitto/passwd admin
# 添加更多用户 (不用 -c)
sudo mosquitto_passwd /etc/mosquitto/passwd device001
sudo mosquitto_passwd /etc/mosquitto/passwd device002
# 设置文件权限
sudo chmod 600 /etc/mosquitto/passwd
sudo chown mosquitto:mosquitto /etc/mosquitto/passwd
原理解析: Mosquitto 使用 PBKDF2-SHA256 算法哈希密码,安全性足够。每个设备建议用独立账号,方便权限管理和问题排查。
步骤 3:配置 TLS 加密 (可选但推荐)
如果设备在外网访问,强烈建议上 TLS 加密。
使用 Let’s Encrypt 免费证书
# 安装 Certbot
sudo apt-get install -y certbot
# 获取证书 (需要域名)
sudo certbot certonly --standalone -d mqtt.yourdomain.com
# 证书位置
# /etc/letsencrypt/live/mqtt.yourdomain.com/fullchain.pem
# /etc/letsencrypt/live/mqtt.yourdomain.com/privkey.pem
修改 Mosquitto 配置
# TLS 监听端口
listener 8883
protocol mqtt
# 证书配置
cafile /etc/letsencrypt/live/mqtt.yourdomain.com/chain.pem
certfile /etc/letsencrypt/live/mqtt.yourdomain.com/fullchain.pem
keyfile /etc/letsencrypt/live/mqtt.yourdomain.com/privkey.pem
# 强制 TLS
require_certificate false
重启服务:
sudo systemctl restart mosquitto
步骤 4:测试连接
命令行测试
# 终端 1:订阅主题
mosquitto_sub -h localhost -p 1883 -u admin -P yourpassword -t "test/topic" -v
# 终端 2:发布消息
mosquitto_pub -h localhost -p 1883 -u admin -P yourpassword -t "test/topic" -m "Hello MQTT!"
如果看到终端 1 收到消息,说明配置成功!
Python 客户端测试
import paho.mqtt.client as mqtt
import time
# 回调函数
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
client.subscribe("test/topic")
def on_message(client, userdata, msg):
print(f"{msg.topic}: {msg.payload.decode()}")
# 创建客户端
client = mqtt.Client()
client.username_pw_set("admin", "yourpassword")
client.on_connect = on_connect
client.on_message = on_message
# 连接
client.connect("localhost", 1883, 60)
client.loop_start()
# 发布消息
for i in range(5):
client.publish("test/topic", f"Message {i}")
time.sleep(1)
time.sleep(3)
client.loop_stop()
client.disconnect()
步骤 5:性能优化
调整系统限制
# 编辑系统限制
sudo nano /etc/security/limits.conf
# 添加以下内容
mosquitto soft nofile 65536
mosquitto hard nofile 65536
Mosquitto 高级配置
# 消息队列优化
max_queued_messages 10000
max_inflight_messages 20
retry_interval 20
# 心跳间隔 (秒)
keepalive_interval 60
# 自动过期 (秒)
autosave_interval 1800
# 客户端超时
timeout_idle 0
监控连接状态
# 查看活跃客户端数
mosquitto_sub -t '$SYS/broker/clients/connected' -h localhost
# 查看消息统计
mosquitto_sub -t '$SYS/broker/messages/#' -h localhost
# 查看负载情况
mosquitto_sub -t '$SYS/broker/load/#' -h localhost
常见问题排查
问题 1:连接被拒绝 (Connection refused)
- 原因: 防火墙阻止 1883 端口
- 解决:
sudo ufw allow 1883/tcp sudo ufw allow 8883/tcp sudo systemctl restart mosquitto
问题 2:认证失败 (Not authorized)
- 原因: 用户名密码错误或密码文件权限不对
-
解决:
# 检查密码文件权限 ls -la /etc/mosquitto/passwd # 应该是 -rw------- mosquitto mosquitto # 重置密码 sudo mosquitto_passwd /etc/mosquitto/passwd admin
问题 3:TLS 连接失败
- 原因: 证书路径错误或权限问题
-
解决:
# 检查证书文件 ls -la /etc/letsencrypt/live/yourdomain/ # Mosquitto 需要读取权限 sudo chmod 644 /etc/letsencrypt/live/yourdomain/*.pem sudo chown mosquitto:mosquitto /etc/letsencrypt/live/yourdomain/*.pem
问题 4:消息丢失
- 原因: QoS 级别设置不当或客户端异常断开
- 解决:
- 关键消息使用 QoS 1 或 QoS 2
- 启用持久化 (persistence true)
- 客户端设置 clean_session=false
问题 5:连接数过多导致性能下降
- 原因: 默认配置不适合高并发
- 解决:
- 调整 max_connections
- 增加系统文件描述符限制
- 考虑集群部署 (多个 Mosquitto 实例)
总结
自建 MQTT 代理服务器其实不难,Mosquitto 这个方案轻量又稳定。关键点是:
- 安全第一:一定要配置认证,外网访问必须上 TLS
- 权限隔离:不同设备用不同账号,方便管理
- 监控到位:善用 $SYS 主题监控运行状态
- 持久化:重要数据开启 persistence 防止丢失
如果是小规模 IoT 项目,单台 Mosquitto 足够支撑几千个设备。规模再大的话,可以考虑 EMQX 这种企业级方案,或者 Mosquitto 集群部署。
希望这篇博客文章对您有所帮助!
相关资源:



