RabbitMQ

RabbitMQ是一个开源的消息队列软件(消息代理),它实现了高级消息队列协议(AMQP)。它主要用于应用程序之间或者同一应用的不同组件之间传递消息,实现了解耦、非阻塞的服务架构。

安装

1
2
3
4
5
6
7
8
# 启动rabbitmq-server
systemctl start rabbitmq-server
# 查询rabbitmq-server
systemctl status rabbitmq-server
# 查看服务器状态
rabbitmqctl status
# 访问本地管理界面
http://0.0.0.0:15672/#/

虚拟主机VHost

虚拟主机(vhost)是一个逻辑上的分组,它允许你在同一个RabbitMQ实例中创建多个独立的工作环境。每个vhost可以拥有自己的队列、交换机、绑定等,并且可以设置不同的权限来控制不同用户对这些资源的访问。使用vhost可以帮助你实现资源的分离,比如你可以为不同的应用或不同的开发环境(如测试环境和生产环境)配置不同的vhost,从而避免它们之间的相互影响。

默认情况下,RabbitMQ提供了一个名为“/”的vhost,所有新创建的用户如果没有特别指定的话,都会被分配到这个默认的vhost中。

1
2
3
4
5
6
# 列出所有虚拟主机
rabbitmqctl list_vhosts
# 创建新的虚拟主机
rabbitmqctl add_vhost <vhost>
# 删除虚拟主机
rabbitmqctl delete_vhost <vhost>

用户User

用户(user)是指连接到RabbitMQ服务器并进行消息发送和接收的实体,它可以是人类用户和其他软件系统或服务。每个用户都需要分配一个或多个角色,这些角色决定了用户可以在特定的vhost中执行哪些操作。例如,用户可能只被授予对某个vhost中的某些队列的读取权限,而没有写入或其他管理权限。

用户与vhost的关系通过权限设置来定义。你可以为每个用户在每个vhost上设置详细的权限,以控制该用户能够执行的操作类型(如配置、写入、读取)。

1
2
3
4
5
6
7
8
9
10
11
12
# 列出所有用户
rabbitmqctl list_users
# 添加新用户
rabbitmqctl add_user <user> <passwd>
# 设置用户标签/角色
rabbitmqctl set_user_tags <user> administrator
# 查看用户的权限
rabbitmqctl list_user_permissions <user>
# 设置用户在指定 vhost 的权限
rabbitmqctl set_permissions -p <vhost> <user> ".*" ".*" ".*"
# 删除用户
rabbitmqctl delete_user <username>

Docker

1
2
3
# rabbitmq: 基础镜像,仅包含 RabbitMQ 核心功能。
# rabbitmq:management: 包含 RabbitMQ 的管理插件(提供 Web 管理界面)。
docker pull rabbitmq:management

执行如下命令启动容器:

1
2
3
4
5
6
7
8
9
10
11
12
13
docker run -d \
--name rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
-v /path/to/rabbitmq-data:/var/lib/rabbitmq \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=password \
rabbitmq:management
# 比如
$ docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -v ~/rabbitmq-data:/var/lib/rabbitmq -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=password rabbitmq:management
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc42faea6833 rabbitmq:management "docker-entrypoint.s…" 2 seconds ago Up 1 second 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, :::5672->5672/tcp, 15671/tcp, 15691-15692/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp, :::15672->15672/tcp rabbitmq

参数说明:

  • -d: 后台运行容器。
  • –name rabbitmq: 为容器指定名称(这里是 rabbitmq)。
  • -p 5672:5672: 映射 RabbitMQ 的 AMQP 协议端口(默认 5672)到主机。
  • -p 15672:15672: 映射 RabbitMQ 的管理界面端口(默认 15672)到主机。
  • -e RABBITMQ_DEFAULT_USER=admin: 设置 RabbitMQ 的默认用户名为 admin。
  • -e RABBITMQ_DEFAULT_PASS=password: 设置 RabbitMQ 的默认密码为 password。
  • /path/to/rabbitmq-data: 主机上的目录,用于存储 RabbitMQ 的持久化数据。
  • /var/lib/rabbitmq: 容器内的 RabbitMQ 数据目录。

管理界面登录

启动容器后,访问 http://localhost:15672 进入 RabbitMQ 管理界面,使用环境变量中设置的用户名 admin 和密码 password(或你自定义的凭据)登录。

登录后即可在 Web 界面中可视化管理虚拟主机(VHosts)、用户(Users)、队列(Queues)、交换机(Exchanges)等。

容器内执行管理命令

在 Docker 容器中,需要通过 docker exec 来执行 rabbitmqctl 管理命令:

1
2
3
4
5
6
# 进入容器交互式 shell
docker exec -it rabbitmq bash

# 或在容器外直接执行命令
docker exec rabbitmq rabbitmqctl list_vhosts
docker exec rabbitmq rabbitmqctl list_users

虚拟主机操作:

1
2
3
4
5
6
# 列出所有虚拟主机
docker exec rabbitmq rabbitmqctl list_vhosts
# 创建新的虚拟主机
docker exec rabbitmq rabbitmqctl add_vhost my_vhost
# 删除虚拟主机
docker exec rabbitmq rabbitmqctl delete_vhost my_vhost

用户操作:

1
2
3
4
5
6
7
8
9
10
11
12
# 列出所有用户
docker exec rabbitmq rabbitmqctl list_users
# 添加新用户
docker exec rabbitmq rabbitmqctl add_user dev_user dev_pass
# 设置用户为管理员角色
docker exec rabbitmq rabbitmqctl set_user_tags dev_user administrator
# 查看用户权限
docker exec rabbitmq rabbitmqctl list_user_permissions dev_user
# 设置用户对指定 vhost 的权限(配置、写入、读取)
docker exec rabbitmq rabbitmqctl set_permissions -p my_vhost dev_user ".*" ".*" ".*"
# 删除用户
docker exec rabbitmq rabbitmqctl delete_user dev_user

注意:容器重启后,通过环境变量 RABBITMQ_DEFAULT_USERRABBITMQ_DEFAULT_PASS 创建的默认用户依然存在,但容器内额外创建的用户和 vhost 取决于数据卷是否持久化。如果挂载了数据卷(-v),重启后数据不会丢失;否则容器删除后新增的用户和 vhost 将不复存在。

常见问题

  • 多vhost 绑定:一个用户可以绑定到多个虚拟主机,这意味着该用户可以根据需要访问不同的工作环境,例如开发环境和测试环境。
  • 共享vhost:一个虚拟主机也可以由多个用户共享,这允许根据团队成员的角色分配不同的访问级别。
  • guest 用户无法远程登录:RabbitMQ 默认禁止 guest 用户从非 localhost 地址登录(即无法通过远程 IP 访问管理界面或连接)。解决方案:创建自定义管理员用户并授予权限,或在 rabbitmq.conf 中设置 loopback_users.guest = false(不推荐生产环境使用)。
  • Docker 容器重启后数据丢失:如果容器启动时未挂载数据卷(-v),容器删除后所有队列、消息、用户和 vhost 配置都会丢失。务必使用 -v /host/path:/var/lib/rabbitmq 持久化数据,或使用 Docker 命名卷 -v rabbitmq_data:/var/lib/rabbitmq
  • 端口说明:RabbitMQ 使用多个端口,常见端口包括:
    • 5672:AMQP 协议端口,供客户端连接(生产者/消费者)
    • 15672:管理界面 HTTP 端口(需要启用 management 插件)
    • 25672:集群节点间通信端口(distributed/Erlang)
  • 忘记密码如何重置:如果忘记了管理员密码,可以进入容器或直接在宿主机上执行命令重置:rabbitmqctl change_password <user> <new_password>。在 Docker 中则为 docker exec rabbitmq rabbitmqctl change_password admin newpass
  • 启用和禁用插件:RabbitMQ 通过插件机制扩展功能,使用 rabbitmq-plugins 命令管理。例如启用延时消息插件或禁用一个插件:
    1
    2
    3
    4
    5
    6
    # 启用 RabbitMQ 延迟消息插件
    docker exec rabbitmq rabbitmq-plugins enable rabbitmq_delayed_message_exchange
    # 禁用管理插件
    docker exec rabbitmq rabbitmq-plugins disable rabbitmq_management
    # 列出已启用插件
    docker exec rabbitmq rabbitmq-plugins list
  • 延迟消息:RabbitMQ 原生不直接支持延迟消息,可以通过安装 rabbitmq_delayed_message_exchange 插件(如上所示)或使用死信队列(DLX)机制模拟。
  • Dead Letter Exchange(死信交换机):当队列中的消息被拒绝、过期或超过队列最大长度时,这些消息可以被重新发送到指定的死信交换机(DLX),从而实现消息的延迟处理、错误隔离或重试逻辑。通过 x-dead-letter-exchange 参数为队列配置死信交换机。