当我们第一次安装好一个 RabbitMQ 之后,我们可能都会通过 Web 页面去管理这个 RabbitMQ,默认情况下,我们第一次使用的默认用户是 guest。

登录成功后,在 admin 选项卡可以查看所有用户:

10-理解VirtualHost - 图1

可以看到,每个用户都有一个 Can access virtual hosts 属性,这个属性是啥意思呢?

今天松哥来和大家稍微捋一捋。

1. 多租户

RabbitMQ 中有一个概念叫做多租户,怎么理解呢?

我们安装一个 RabbitMQ 服务器,每一个 RabbitMQ 服务器都能创建出许多虚拟的消息服务器,这些虚拟的消息服务器就是我们所说的虚拟主机(virtual host),一般简称为 vhost。

本质上,每一个 vhost 都是一个独立的小型 RabbitMQ 服务器,这个 vhost 中会有自己的消息队列、消息交换机以及相应的绑定关系等等,并且拥有自己独立的权限,不同的 vhost 中的队列和交换机不能互相绑定,这样技能保证运行安全又能避免命名冲突。

我们并不需要特别的去看待 vhost,他就跟普通的物理 RabbitMQ 一样,不同的 vhost 能够提供逻辑上的分离,确保不同的应用消息队列能够安全独立运行。

要我来说,我们该怎么看待 vhost 和 RabbitMQ 的关系呢?RabbitMQ 相当于一个 Excel 文件,而 vhost 则是 Excel 文件中的一个个 sheet,我们所有的操作都是在某一个 sheet 上进行操作。

本质上来说,vhost 算是 AMQP 协议中的概念。

我们之前创建的队列、交换机、交换机和队列的绑定关系等等都是在某一个vhost下创建的。而不是直接在RabbitMQ上创建的。所以我们如果新建了一个用户zhangsan,它必须要有访问某个vhost的权限,否则zhangsan这个账号将不能创建队列、交换机等等。

演示:新建一个用户zhangsan,然后在mq_receive_message工程的manual模块使用张三这个账号去发消息到消息队列中。

第一步:在RabbitMQ的web管理页面的admin选项卡中新建一个用户zhangsan,密码设置成123,Tags选择Admin,如下图所示

10-理解VirtualHost - 图2

注意此时张三的can access virtual hosts属性的值是No access的

10-理解VirtualHost - 图3

然后注销登录,使用zhangsan的账号登录到RabbitMQ的web管理页面

第二步:修改manual模块的application.properties配置文件

  1. spring.rabbitmq.host=localhost
  2. spring.rabbitmq.port=5672
  3. spring.rabbitmq.username=zhangsan
  4. spring.rabbitmq.password=123
  5. spring.rabbitmq.virtual-host=/
  6. #设置消息消费者的手动确认
  7. spring.rabbitmq.listener.simple.acknowledge-mode=manual

第三步:启动SpringBoot应用,在浏览器访问http://localhost:8080/send,我们发现控制台报错了

10-理解VirtualHost - 图4

第四步:给zhangsan这个用户添加/的访问权限

单击zhangsan

10-理解VirtualHost - 图5

点击set permission

10-理解VirtualHost - 图6

设置完成之后zhangsan的can access virtual hosts属性的值已经是/了

10-理解VirtualHost - 图7

第五步:重新启动SpringBoot应用,浏览器再次访问http://localhost:8080/send,发现可以发送消息了

10-理解VirtualHost - 图8

2. 命令行创建vhost

先来看看如何通过命令行创建 vhost。

因为松哥这里的 RabbitMQ 是用 docker 安装的,所以我们首先进入到 docker 容器中:

  1. $ docker exec -it rabbit01 /bin/bash

然后执行如下命令创建一个名为 /myvh 的 vhost:

  1. $ rabbitmqctl add_vhost myvh

最终执行结果如下:

10-理解VirtualHost - 图9

然后通过如下命令可以查看已有的 vhost:

  1. $ rabbitmqctl list_vhosts

10-理解VirtualHost - 图10

当然这个命令也可以添加两个选项 name 和 tracing,name 表示 vhost 的名称,tracing 则表示是否使用了 tracing 功能(tracing 可以帮助追踪 RabbitMQ 中消息的流入流出情况),如下图:

10-理解VirtualHost - 图11

可以通过如下命令删除一个 vhost:

  1. $ rabbitmqctl delete_vhost myvh

10-理解VirtualHost - 图12

注意:当删除一个 vhost 的时候,与这个 vhost 相关的消息队列、交换机以及绑定关系等,统统都会被删除。

给一个用户设置 vhost:

  1. $ rabbitmqctl set_permissions -p myvh guest ".*" ".*" ".*"

10-理解VirtualHost - 图13

前面参数都好说,最后面三个 ".*" 含义分别如下:

  • 用户在所有资源上都拥有可配置权限(创建/删除消息队列、创建/删除交换机等)。
  • 用户在所有资源上都拥有写权限(发消息)。
  • 用户在所有资源上都拥有读权限(消息消费,清空队列等)。

禁止一个用户访问某个 vhost:

  1. $ rabbitmqctl clear_permissions -p myvh guest

10-理解VirtualHost - 图14

3. 管理页面创建 vhost

当然我们也可以在网页端管理 vhost:

在 admin 选项卡中,点击右边的 Virtual Hosts,如下:

10-理解VirtualHost - 图15

然后点击下边的 Add a new virtual host ,可以添加一个新的 vhost:

10-理解VirtualHost - 图16

进入到某一个 vhost 之后,可以修改其权限以及删除一个 vhost,如下图:

10-理解VirtualHost - 图17

我们也可以给某个用户设置vhost,如下图所示先进入某一个用户之后,就可以编辑用户的权限了。

10-理解VirtualHost - 图18

4. 用户管理

因为 vhost 通常跟用户一起出现,所以这里我也顺便说下 user 的相关操作。

添加一个用户名为 javaboy,密码为 123 的用户,方式如下:

  1. $ rabbitmqctl add_user javaboy 123

10-理解VirtualHost - 图19

通过如下命令可以修改用户密码(将 javaboy 的密码改为 123456)

  1. $ rabbitmqctl change_password javaboy 123456

10-理解VirtualHost - 图20

通过如下命令可以验证用户密码:

  1. $ rabbitmqctl authenticate_user javaboy 123456

验证成功和验证失败的情况分别如下:

10-理解VirtualHost - 图21

通过如下命令可以查看当前的所有用户:

  1. $ rabbitmqctl list_users

10-理解VirtualHost - 图22

第一列是用户名,第二列是用户角色。

关于用户角色,我在上篇文章中已经聊过了,这里就不再赘述。传送门:RabbitMQ 管理页面该如何使用

给用户设置角色的命令如下(给 javaboy 设置 administrator 角色):

  1. $ rabbitmqctl set_user_tags javaboy administrator

10-理解VirtualHost - 图23

最后,删除一个用户的命令如下:

  1. $ rabbitmqctl delete_user javaboy

10-理解VirtualHost - 图24