用 Docker 部署 RabbitMQ:从入门到实战全细节

4066 字
20 分钟
用 Docker 部署 RabbitMQ:从入门到实战全细节

这是写给未来自己的 RabbitMQ + Docker 全流程备忘:一次搞明白端口、账号、虚拟主机、持久化、集群和常见坑,以后再搭环境直接照着抄就行。

一、RabbitMQ 是什么,为什么要自己部署?#

一句话版本:

  • RabbitMQ 是一个实现了 AMQP 协议的消息中间件,常用于解耦服务、削峰填谷、异步处理任务等场景。

典型用法:

  • Web 请求里只负责把任务写入队列,真实耗时逻辑交给后台消费者慢慢处理;
  • 多个微服务之间,用消息队列传递事件(订单创建、支付成功、库存变更……);
  • 延迟任务、重试队列、死信队列等等。

选择自己用 Docker 部署而不是托管服务的理由:

  • 成本更可控:学习 / 内网环境不需要云上托管 MQ;
  • 方便调试:本地就能起一套完整的 RabbitMQ 环境;
  • 可迁移性强:Docker 化后,迁机器基本是复制配置 + 数据卷。

本文默认你已经对 “消息队列是什么” 有一点点概念,重点放在:

  1. 如何用 Docker 跑起 RabbitMQ,并打开可视化管理界面;
  2. 如何设置账号、密码、虚拟主机、权限
  3. 如何做好数据持久化,避免重建容器时配置丢失;
  4. 如何用 docker-compose 管理 RabbitMQ;
  5. (选读)如何简单拉一个 多节点集群
  6. 部署中高频踩坑与排查思路。

二、镜像选择与基础概念#

RabbitMQ 官方镜像在 Docker Hub 上维护,推荐的几个标签:

  • rabbitmq:3-management
    • 带 Web 管理控制台,是开发 / 调试最常用的版本。
  • rabbitmq:3
    • 纯核心服务,不带 Web UI,适合资源有限或生产环境配监控系统。
  • rabbitmq:3-management-alpine
    • 基于 Alpine 的轻量版,体积更小。

为了方便,我们后面都用:

  • rabbitmq:3-management

默认端口一览#

RabbitMQ 镜像启动后,常见端口:

  • 5672:AMQP 协议端口(应用连 MQ 用的端口);
  • 15672:Web 管理控制台端口;
  • (可选)5671:AMQP over TLS;
  • (可选)15671:管理界面 HTTPS;
  • (可选)25672:集群节点间通信端口。

后文的端口映射都围绕这些展开。

默认账号密码#

RabbitMQ 默认会创建一个:

  • 用户名:guest
  • 密码:guest

重要限制

  • 默认 guest/guest 只能本机访问localhost),如果你从远程 IP 访问,会被拒绝。

这也是为什么生产环境一定要创建自己的账号,并关掉或限制 guest 的原因。

三、拉取镜像并做第一次试跑#

先拉镜像(确保 Docker 已安装并能正常工作):

Terminal window
docker pull rabbitmq:3-management

确认镜像:

Terminal window
docker images | grep rabbitmq

1. 最小运行示例(仅用于本地试用)#

先用一个最简单的命令把 RabbitMQ 跑起来:

Terminal window
docker run --name my-rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
-d rabbitmq:3-management

参数含义:

  • --name my-rabbitmq:容器名称,后续方便用 docker logs my-rabbitmq 来看日志等;
  • -p 5672:5672:暴露核心的 AMQP 服务端口;
  • -p 15672:15672:暴露 Web 管理控制台;
  • -d:后台运行;
  • rabbitmq:3-management:使用带管理控制台的官方镜像。

启动后查看容器状态:

Terminal window
docker ps

2. 打开 Web 管理控制台#

浏览器访问:

http://127.0.0.1:15672

默认账号:

  • 用户名:guest
  • 密码:guest

能够登录就说明 RabbitMQ 已经跑起来了。

不过,目前这个环境还存在几个问题:

  • 没有数据卷,容器删了配置就没了(包括用户、虚拟主机、队列持久化等);
  • 仍然使用默认 guest/guest,并且理论上只允许本机登录;
  • 没有任何自定义配置(如集群、TLS、限流等)。

接下来一步步补齐。

四、数据持久化:挂载卷与配置目录#

RabbitMQ 的 Docker 镜像中,主要有两个值得挂载的目录:

  • /var/lib/rabbitmq:数据目录(队列、消息、元数据等);
  • /etc/rabbitmq:配置文件目录(rabbitmq.conf / advanced.config 等)。

实践中,至少挂在 /var/lib/rabbitmq,否则重建容器时数据容易消失。
如果你有自定义配置(比如特定策略、TLS 设置等),再挂 /etc/rabbitmq

1. 创建宿主机目录#

以 Linux / macOS 为例:

Terminal window
mkdir -p ~/docker-data/rabbitmq/data
mkdir -p ~/docker-data/rabbitmq/conf

Windows(PowerShell)类似:

Terminal window
mkdir C:\docker-data\rabbitmq\data
mkdir C:\docker-data\rabbitmq\conf

2. 用数据卷重新运行容器#

先停掉之前的试用容器:

Terminal window
docker stop my-rabbitmq
docker rm my-rabbitmq

再用带卷的命令重新启动:

Terminal window
docker run --name my-rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
-v ~/docker-data/rabbitmq/data:/var/lib/rabbitmq \
-v ~/docker-data/rabbitmq/conf:/etc/rabbitmq \
-d rabbitmq:3-management

现在,RabbitMQ 的数据和配置文件都落在宿主机,对应目录中。
后面添加的用户、虚拟主机、队列等信息都会持久化保存。

注意:刚启动时 /etc/rabbitmq 可能是空的,但只要我们不挂载配置文件,RabbitMQ 会用默认配置启动。这时挂载 conf 目录主要是为将来扩展准备。

五、创建自己的用户与虚拟主机#

现实中你几乎不应该用 guest/guest(特别是在暴露到网络时)。
推荐做法:

  1. 新建一个自己的管理员用户;
  2. 新建一个业务用虚拟主机(vhost);
  3. 赋予该用户对 vhost 的权限;
  4. 根据需要关闭或限制 guest 用户。

1. 通过 Web UI 创建#

进入 http://127.0.0.1:15672,默认 guest/guest 登录。

创建新用户:

  • 进入 Admin 标签页;
  • Add a user
    • Username:比如 app_user
    • Password:自行设定一个复杂点的密码
    • Tags:选 administrator(也可以按需控制权限)
    • 点击 Add user

创建虚拟主机:

  • 仍然在 Admin 标签页;
  • Virtual HostsAdd a new virtual host
  • Name:比如 /appapp_vhost
  • 点击 Add virtual host

给用户授权:

  • AdminUsers 找到 app_user
  • 点击用户名进入详情页;
  • Permissions 部分选择刚刚创建的 vhost(比如 /app);
  • 配置 Configure / Write / Read 权限(简单起见可以写 .*);
  • 点击 Set permission

之后,客户端只需要使用:

  • user:app_user
  • pass:你设置的密码
  • vhost:/app(或 app_vhost

即可连接到 RabbitMQ,并在这个 vhost 中创建交换机和队列。

2. 通过命令行创建(可脚本化)#

如果你想把这些写进自动化脚本,可以用 rabbitmqctl / rabbitmq-plugins 等命令。

先进入容器:

Terminal window
docker exec -it my-rabbitmq bash

容器内部执行:

Terminal window
# 创建用户
rabbitmqctl add_user app_user 'Your_Strong_Password'
# 给用户加管理员标签(可选)
rabbitmqctl set_user_tags app_user administrator
# 创建虚拟主机
rabbitmqctl add_vhost /app
# 为用户在 /app vhost 上设置权限
rabbitmqctl set_permissions -p /app app_user ".*" ".*" ".*"
# (按需)禁用 guest 用户的远程访问,或者直接删掉 guest
# 禁用 guest 最常见做法是只允许本地访问,这通常通过配置文件完成

退出容器:

Terminal window
exit

这些命令产生的用户 / vhost 配置同样会写入 /var/lib/rabbitmq,即已经被我们持久化。

六、用 docker-compose 管理 RabbitMQ#

当你不想每次都敲上面那串 docker run 命令时,就是 docker-compose 出场的时候。

在一个目录(比如 deploy/rabbitmq)下创建 docker-compose.yml

version: "3.9"
services:
rabbitmq:
image: rabbitmq:3-management
container_name: my-rabbitmq
restart: always
ports:
- "5672:5672" # AMQP
- "15672:15672" # Web 管理界面
environment:
RABBITMQ_DEFAULT_USER: app_user
RABBITMQ_DEFAULT_PASS: Your_Strong_Password
RABBITMQ_DEFAULT_VHOST: /app
volumes:
- ./data:/var/lib/rabbitmq
- ./conf:/etc/rabbitmq

这里做的事情:

  • 通过环境变量设置了一个默认用户和虚拟主机:
    • 容器第一次启动时,会自动创建 app_user / /app
    • 后续再重启不会重复创建(数据已在 ./data 里)。
  • ./data./conf 做挂载点,让数据和配置都持久化在当前目录。

在该目录下运行:

Terminal window
docker compose up -d

查看状态:

Terminal window
docker compose ps

关闭服务:

Terminal window
docker compose down

只要不加 -v./data 里的内容会一直保留。

小建议:不要把真实密码硬编码在仓库里的 compose 文件中,可以用 .env 或部署系统的 Secret 管理。

使用 .env 管理账号密码#

docker-compose.yml 同目录下创建 .env

RABBITMQ_USER=app_user
RABBITMQ_PASS=Your_Strong_Password
RABBITMQ_VHOST=/app

然后在 docker-compose.yml 中这么写:

environment:
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASS}
RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_VHOST}

这样,你可以在不同环境用不同 .env 文件,而 compose 文件本身保持不变。

七、应用如何连接 Docker 中的 RabbitMQ#

无论你用什么语言,本质上连接参数都差不多:

  • 主机:127.0.0.1(本地)或服务器 IP / 域名;
  • 端口:5672(默认 AMQP 端口);
  • 用户名 / 密码:RABBITMQ_DEFAULT_USER / RABBITMQ_DEFAULT_PASS
  • 虚拟主机:RABBITMQ_DEFAULT_VHOST

以 Node.js + amqplib 为例:

Terminal window
npm install amqplib
import amqp from "amqplib";
const host = "127.0.0.1";
const port = 5672;
const user = "app_user";
const pass = "Your_Strong_Password";
const vhost = "/app";
const url = `amqp://${encodeURIComponent(user)}:${encodeURIComponent(
pass
)}@${host}:${port}${vhost}`;
async function main() {
const conn = await amqp.connect(url);
const channel = await conn.createChannel();
const queue = "demo_queue";
await channel.assertQueue(queue, {
durable: true,
});
await channel.sendToQueue(queue, Buffer.from("hello from docker-rabbitmq"), {
persistent: true,
});
console.log("消息已发送");
await channel.close();
await conn.close();
}
main().catch(console.error);

通过这个 demo,你可以检查:

  • 队列是否创建成功(在 Web 控制台 Queues 标签页能看到);
  • 消息是否成功发送、持久化。

八、消息持久化与可靠性:队列、消息、确认机制#

RabbitMQ 的 “持久化” 不是一开镜像就有,需要满足几个条件:

  1. 队列本身要设置为 durable: true
  2. 消息发送时需要设置 deliveryMode=2(大部分语言里就是 persistent: true);
  3. 节点的数据目录 /var/lib/rabbitmq 要挂载到宿主机;
  4. 最好启用 publisher confirms,确保消息确实被 Broker 接收。

否则,Broker 重启或容器销毁时,消息和队列可能会丢。

1. 队列持久化#

上面 Node.js 示例中的:

await channel.assertQueue(queue, {
durable: true,
});

中的 durable: true 就是设置队列为持久化队列。

2. 消息持久化#

发送消息时:

channel.sendToQueue(queue, Buffer.from("..."), {
persistent: true,
});

这里的 persistent: true 即把 delivery_mode 设置为 2。

3. Publisher Confirms(发布确认)#

为了确保消息真正被 Broker 接收(而不是在网络途中丢失),推荐:

  • 使用 confirm channel,即在 Node.js 中 createConfirmChannel
  • 每发送一批消息都等 RabbitMQ 返回 ack。

简单示例:

const confirmChannel = await conn.createConfirmChannel();
confirmChannel.sendToQueue(
queue,
Buffer.from("message with confirm"),
{ persistent: true },
(err, ok) => {
if (err) {
console.error("消息未被确认", err);
} else {
console.log("消息已被 Broker 确认");
}
}
);

这是深入生产环境时必备的可靠性手段。

九、(进阶)简单 RabbitMQ 集群部署示例#

RabbitMQ 支持通过 Erlang 分布式机制组建多节点集群。
这里给一个教学向的 Docker Compose 集群例子,帮助理解结构,不一定直接用于生产。

提示:RabbitMQ 集群配置本身比较讲究主机名解析、cookie、磁盘节点 / 内存节点等,生产环境建议参考官方文档或专门的部署教程,这里只做一个入门示例。

1. 基本思路#

  • 准备两个节点 rabbit1rabbit2,加入同一个集群;
  • 用同一份 ERLANG_COOKIE,保证它们能互相通信;
  • rabbit2 加入到以 rabbit1 为核心的集群。

2. 示例 docker-compose.yml(精简版)#

在一个单独的目录(如 deploy/rabbitmq-cluster)创建:

version: "3.9"
services:
rabbit1:
image: rabbitmq:3-management
hostname: rabbit1
container_name: rabbit1
environment:
RABBITMQ_ERLANG_COOKIE: "MY_SECRET_COOKIE"
RABBITMQ_DEFAULT_USER: app_user
RABBITMQ_DEFAULT_PASS: Your_Strong_Password
RABBITMQ_DEFAULT_VHOST: /app
ports:
- "5672:5672"
- "15672:15672"
volumes:
- ./data/rabbit1:/var/lib/rabbitmq
rabbit2:
image: rabbitmq:3-management
hostname: rabbit2
container_name: rabbit2
environment:
RABBITMQ_ERLANG_COOKIE: "MY_SECRET_COOKIE"
depends_on:
- rabbit1
volumes:
- ./data/rabbit2:/var/lib/rabbitmq

启动集群:

Terminal window
docker compose up -d

3. 手动把 rabbit2 加入 rabbit1#

进入 rabbit2 容器:

Terminal window
docker exec -it rabbit2 bash

执行如下命令(注意有停服务 / 加入集群 / 启服务的顺序):

Terminal window
rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbit1
rabbitmqctl start_app

回到 rabbit1 的 Web 管理界面 http://127.0.0.1:15672,登录后在 Overview 页面就能看到集群节点列表中出现 rabbit1rabbit2

再次强调:生产环境需要考虑磁盘节点(disc)与内存节点(ram)、镜像队列策略(HA)、跨机房网络延迟等,这里只是一个把多节点拉起来的起步版本。

十、与反向代理 / 安全策略的关系#

RabbitMQ 默认不是 HTTP 服务,但它有一个 Web 管理端口(15672),你可能会想把它:

  • 通过 Nginx 做一层反向代理;
  • 绑定域名并加上 HTTPS;
  • 再加上 Basic Auth 或 IP 白名单保护。

一个典型的 Nginx 片段可能是这样:

server {
listen 80;
server_name rabbitmq-admin.your-domain.com;
location / {
proxy_pass http://127.0.0.1:15672;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

实战中,还会继续叠加:

  • listen 80 换成 listen 443 ssl 字段,并配置证书;
  • 通过 allow / deny 控制可访问 IP;
  • 或在前面加一个认证层(比如 Basic Auth)。

对于 5672(AMQP 端口),一般不会走反向代理,而是直接在内网暴露(局域网或安全组控制)。

十一、常见坑与排查思路#

这一节专门列一些部署 RabbitMQ 时常见的问题和排查方法。

1. 容器一直重启 / 退出#

首先看日志:

Terminal window
docker logs my-rabbitmq

常见错误包括:

  • 权限问题(对 /var/lib/rabbitmq/etc/rabbitmq 目录无写入权限);
  • 配置文件语法错误(尤其是自己写了 rabbitmq.confadvanced.config);
  • ERLANG_COOKIE 不一致(在做集群时)。

排查建议:

  • 先去掉自定义配置和卷,只用最小命令确认基础镜像没问题;
  • 再一步步加上卷和配置;
  • 没必要一上来就搞集群,把单节点跑稳再说。

2. 端口被占用#

如果启动时报 bind (..) failed: port is already allocated,说明 5672 或 15672 已经被占用。

解决:

  • 换宿主机端口映射,比如:
ports:
- "5673:5672"
- "15673:15672"

连接时就用 5673 / 15673。

3. 客户端连接被拒绝 / 授权失败#

常见错误消息:

  • ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
  • ACCESS_REFUSED - vhost '/app' refused.

检查清单:

  • 用户名、密码是否正确;
  • 指定的 vhost 是否存在;
  • 是否给该用户在 vhost 上授权了 Configure/Read/Write 权限;
  • 是否使用 guest/guest 在远程访问(默认不允许)。

4. 消费者和队列的关系混乱#

有时候你会发现:

  • 队列里看起来有消息,但消费者收不到;
  • 或者消费者连接的 vhost / queue 与你在 Web 上看的不一样。

排查要点:

  • 确认 vhost:RabbitMQ 多个 vhost 相互隔离,很容易“连错房间”;
  • 确认队列名:保证生产者和消费者使用的队列名完全一致;
  • 确认 exchange 与 binding:尤其是在用 topic / direct / fanout 交换机时。

5. 性能问题与监控#

RabbitMQ 的性能受多因素影响:

  • 磁盘 IO(消息持久化时尤其明显);
  • 网络延迟和带宽;
  • 消费者 ack 策略(是否开启手动 ack、防止消息在未确认时大量堆积);
  • prefetch(basic.qos)设置是否合理。

排查时可以:

  • 打开 Web 控制台的 Overview / Queues 观察 rate;
  • 设置合理的 prefetch 值(比如每个消费者一次处理 50 条);
  • 避免在一个 queue 上堆积海量未消费完的消息。

十二、升级、备份与回滚策略#

部署好以后,不可避免要面对版本升级和灾难恢复,这里简单给一套操作习惯。

1. 升级镜像版本#

前提:你已经用 docker-compose 部署,并挂载了数据卷。

步骤:

  1. 修改 docker-compose.yml 中的镜像标签,例如从 rabbitmq:3.11-management 升到 rabbitmq:3.13-management

  2. 拉取新镜像:

    Terminal window
    docker compose pull
  3. 重启服务:

    Terminal window
    docker compose up -d
  4. 观察日志和 Web 控制台,确认队列 / 用户 / 虚拟主机等都正常。

如果发现严重问题:

  • 把镜像标签改回旧版本;
  • 再次 docker compose up -d,数据仍然在卷里。

2. 数据备份#

最简单粗暴的方式:

  • 停掉服务(确保数据一致性):

    Terminal window
    docker compose down
  • 打包 ./data 目录(对应 /var/lib/rabbitmq):

    Terminal window
    tar czf rabbitmq-data-backup-$(date +%Y%m%d).tar.gz ./data
  • 把压缩包丢到异地存储(对象存储、另一台机器等)。

更细粒度的备份:

  • 使用 rabbitmq-dump-queue 等工具导出关键队列数据;
  • 使用集群 + 镜像队列来提升高可用性。

十三、从零到可用:RabbitMQ + Docker 部署清单#

最后,把本文所有关键步骤压缩成一份 checklist,方便以后快速回顾:

  1. 拉镜像docker pull rabbitmq:3-management
  2. 最小试跑(验证环境):docker run --name my-rabbitmq -p 5672:5672 -p 15672:15672 -d rabbitmq:3-management
  3. 确认 Web 控制台可访问:浏览器打开 http://127.0.0.1:15672,默认 guest/guest 登录;
  4. 准备数据卷目录~/docker-data/rabbitmq/data~/docker-data/rabbitmq/conf
  5. 用卷重建容器,挂载 /var/lib/rabbitmq(必选)和 /etc/rabbitmq(可选);
  6. 为生产 / 项目创建自己的用户与虚拟主机,并授权;
  7. 写一个 docker-compose.yml,把镜像、端口、环境变量、卷和 restart: always 都写进去;
  8. 在应用中正确配置连接参数(host/port/user/pass/vhost),并使用持久化队列和消息;
  9. (进阶)需要高可用时,准备多节点集群并配置镜像队列策略;
  10. 定期备份数据卷,升级时小步慢跑,保留回滚路径。

做到这里,你就有了一套 可复用、可迁移、可调试 的 RabbitMQ Docker 部署方案。
下一次再遇到 “要不要搭一个 MQ 环境” 的需求,只需要改一改 compose 里的账号、端口和目录,就能迅速复制一整套环境出来,而不必再从零翻文档、踩坑。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
用 Docker 部署 RabbitMQ:从入门到实战全细节
https://firefly.cuteleaf.cn/posts/docker-rabbitmq-deploy/
作者
Airio_
发布于
2026-02-26
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Airio_
Hello, I'm Airio_.
公告
欢迎来到OfoCa Space。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
6
分类
1
标签
16
总字数
18,733
运行时长
0
最后活动
0 天前

目录