关系型数据库解决"业务核心数据"(订单、用户、账户),但物联网 / 实时消息 / 文档型数据这些场景,传统 RDBMS 反而显得笨重:JSON 文档要拆成多张表、消息上行要支持 publish/subscribe、时序数据要写一条立刻收一条。MongoDB(文档数据库)+ Mosquitto(MQTT broker)就是这个组合的"老搭档"——前者存灵活结构的数据,后者负责把设备/客户端消息实时收上来。这篇文章把这两个在 Docker 里的部署、配置、客户端连接一次性说清楚。
阅读对象:做 IoT 网关、需要落地 JSON 设备数据;做聊天/推送需要轻量消息中间件;想给应用加 publish/subscribe 能力的后端工程师。
覆盖范围:MongoDB 4.x 容器启动、admin 库认证、连接字符串、备份恢复;Eclipse Mosquitto 配置文件、密码文件、客户端工具(MQTTBox)。
一、为什么是 MongoDB + Mosquitto
| 场景 | 关系型数据库 | MongoDB | MQTT |
|---|
| 设备上报 JSON 文档 | 拆多张表,麻烦 | 直接存 BSON,灵活 | 上行通道 |
| 实时控制指令下发 | 轮询,延迟高 | 不擅长 | pub/sub,毫秒级 |
| 设备状态变更通知 | 触发器 + 轮询 | Change Stream | 天然支持 |
| 一台服务器几万台设备 | 撑不住 | 水平分片 | 百万级连接 |
| 数据查询分析 | 强 | 中(聚合管道) | 不存数据 |
典型组合:设备 → Mosquitto(MQTT broker)→ 业务后端消费 → 写入 MongoDB → 前端 / BI 查询。Mosquitto 是"水管",MongoDB 是"水池"。
二、MongoDB 4.x 容器化
2.1 拉取与启动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| # 拉镜像
docker pull mongo:4.4.5-bionic
# 用 docker compose 启动(推荐)
cat << 'EOF' > docker-compose.yml
version: '3'
services:
mongo:
image: mongo:4.4.5-bionic
container_name: mongo
restart: always
ports:
- "27017:27017"
volumes:
- /home/docker/mongo/data:/data/db
- /home/docker/mongo/conf:/data/configdb
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: {{REDACTED}}
command: ["--auth"]
EOF
docker-compose up -d
|
关键参数:
command: ["--auth"] 开启访问控制(不带 --auth 等于"裸奔",任意客户端可读写)MONGO_INITDB_ROOT_USERNAME/PASSWORD:初始化 root 账号(仅在首次启动未挂载数据时生效)
2.2 mongo.conf 配置示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| # /home/docker/mongo/conf/mongo.conf
storage:
dbPath: /data/db
journal:
enabled: true
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
net:
port: 27017
bindIp: 0.0.0.0
processManagement:
fork: true
pidFilePath: /var/run/mongodb.pid
security:
authorization: enabled
|
2.3 客户端连接字符串
1
| mongodb://admin:{{REDACTED}}@internal.example.com:27017/?authSource=admin
|
| 元素 | 说明 |
|---|
mongodb:// | 协议 |
admin:{{REDACTED}} | 账号:密码(脱敏占位) |
internal.example.com:27017 | 宿主机 + 端口 |
?authSource=admin | 认证库(root 账号必须在 admin 库认证) |
2.4 常见坑
- 重启后 admin 密码失效:旧版 MongoDB 镜像在 data 卷有数据时不会重新执行 init 脚本。要重置密码:先不带
--auth 启动 → 进 mongo shell 改 admin.system.users → 重启。 - 时区:MongoDB 存的是 UTC,前端展示时按业务时区(
Asia/Shanghai)+ 8 小时。 - 大文档 16MB 上限:单文档超过 16MB 会写入失败,IoT 大数据要拆成多条或改用 GridFS。
三、Eclipse Mosquitto(MQTT Broker)
Mosquitto 是 Eclipse 基金会维护的轻量级 MQTT broker,单机能撑百万级连接(取决于内存和 fd 上限),是 IoT 领域的"事实标准"。
3.1 拉取与启动
1
| docker pull eclipse-mosquitto
|
3.2 目录结构
1
2
3
| /mosquitto/data # 持久化数据
/mosquitto/log # 日志
/mosquitto/config # 配置 + 密码文件
|
宿主机创建这三个目录并赋权:
1
2
3
| mkdir -p /mosquitto/{data,log,config}
chmod -R 755 /mosquitto
chmod -R 777 /mosquitto/log
|
3.3 配置文件 mosquitto.conf
1
2
3
4
5
6
7
| persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
# 关闭匿名模式(生产环境必开)
allow_anonymous false
password_file /mosquitto/config/pwfile.conf
|
3.4 创建密码文件
1
2
3
4
5
6
7
| touch /mosquitto/config/pwfile.conf
chmod -R 755 /mosquitto/config/pwfile.conf
# 在容器内执行(不要在宿主机直接编辑,会被容器覆盖)
docker exec -it <container_id> bash
mosquitto_passwd -b /mosquitto/config/pwfile.conf hangge 123
# -b 表示非交互式(用户名 hangge 密码 123,生产请用强密码)
|
3.5 启动容器
1
2
3
4
5
6
| docker run -it \
-p 1883:1883 -p 9001:9001 \
-v /mosquitto/config/mosquitto.conf:/mosquitto/config/mosquitto.conf \
-v /mosquitto/data \
-v /mosquitto/log \
eclipse-mosquitto
|
端口说明:
1883:MQTT 默认 TCP 端口(明文)9001:WebSocket 端口(前端订阅用)8883:MQTT over TLS(加密)—— 启动时再加 -p 8883:8883 并配置证书
3.6 客户端连接
| 工具 | 平台 | 用途 |
|---|
| MQTTBox | Chrome 扩展 / 桌面 | 测试用,支持 publish + subscribe + 多种协议 |
| MQTTX | 跨平台桌面(Mac/Win/Linux) | EMQ 出品,UI 现代,推荐 |
| mosquitto_sub/pub | CLI | 服务端调试,脚本化测试 |
| Paho | Java/Python/JS 库 | 应用集成 |
MQTTBox 连接示例:
1
2
3
4
5
6
7
8
| Protocol: mqtt://
Host: internal.example.com
Port: 1883
Username: hangge
Password: 123
Client ID: mqttbox_001
Topic: iot/sensor/temperature
QoS: 1
|
命令行测试:
1
2
3
4
5
6
7
8
| # 订阅
mosquitto_sub -h internal.example.com -p 1883 \
-u hangge -P 123 -t "iot/#" -v
# 发布
mosquitto_pub -h internal.example.com -p 1883 \
-u hangge -P 123 -t "iot/sensor/temperature" \
-m '{"value": 25.6, "ts": 1700000000}'
|
四、IoT 落地架构示例
1
2
3
4
5
6
7
8
9
10
| [设备/传感器] [前端 / 业务系统]
│ publish ▲ subscribe
▼ │
┌─────────────┐ consume ┌─────────┐ │ 写入
│ Mosquitto │ ────────► │ 后端服务 │ ──┘
│ (1883/8883) │ │ (Spring │ MongoDB
└─────────────┘ │ Boot) │ ┌──────────┐
└─────────┘ │ Mongo │
│ Cluster │
└──────────┘
|
| 组件 | 作用 | 选型提示 |
|---|
| 设备端 SDK | paho / mqtt.js / NanoMQ | 嵌入式选 C SDK |
| Broker | Mosquitto / EMQX / VerneMQ | 单机 Mosquitto,集群 EMQX |
| 消费后端 | Spring Boot / Node.js | 设备量大考虑 EMQX Rule Engine 直接落库 |
| 持久化 | MongoDB / InfluxDB / TimescaleDB | 文档型选 MongoDB,时序选时序库 |
五、扩展阅读