# 多租户与权限:vhost

每一个 RabbitMQ 服务器都能创建 虚拟的消息服务器,称之为 虚拟主机(virtual host),简称 vhost

vhost 本质上是一个独立的小型 RabbitMQ 服务器,拥有自己独立的队列、交换器、绑定关系等,并且 拥有自己独立的权限

vhost 可避免队列和交换器等命名冲突,vhost 之间是绝对隔离的,无法将 vhost1 中的交换器与 vhost2 中的队列进行绑定,这样的机制既保证了安全性,又确保可移植性。

如果使用的 RabbitMQ 达到一定规模的时候,建议用户对业务功能、场景进行归类区分,并分配独立的 vhost

vhost 是 AMQP 概念的基础,客户端在联机的时候 必须指定一个 vhost。RabbitMQ 默认创建的 vhost 为 /,使用默认的用户名 guest 和密码 guest 就可以访问它。但是为了安装和方便,建议重新建立一个新的用户来访问它。

下面对 rabbitmqctl 进行讲解

# 创建 vhost:add_host

rabbitmqctl add_host {vhost}

vhost: 就是 vhost 名称
1
2
3

实践练习

[root@study ~]# rabbitmqctl add_vhost vhost1
Creating vhost "vhost1"
1
2

# vhost 查看:list_vhosts

查看 vhost 的相关信息

rabbitmqctl list_vhosts [vhostinfoitem...]

vhostinfoitem 参数:
	name: vhost 名称
	tracing:表示是否使用了 RabbitMQ 的 trace 功能。trace 功能 RabbitMQ 扩展中讲解
1
2
3
4
5

实践练习

[root@study ~]# rabbitmqctl list_vhosts name tracing
Listing vhosts
vhost1	false
/	    false

# 打开 trace 功能
[root@study ~]# rabbitmqctl trace_on
Starting tracing for vhost "/"

[root@study ~]# rabbitmqctl list_vhosts name tracing
Listing vhosts
vhost1	false
/	    true			# 可以看到这里变成了 true
	
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 删除 vhost:delete_host

rabbitmqctl delete_host {vhost}
1

删除一个 vhost ,同时也会删除下面的队列、交换器、绑定关系、用户权限、参数和策略等信息。

实践练习

[root@study ~]# rabbitmqctl delete_vhost vhost1
Deleting vhost "vhost1"

[root@study ~]# rabbitmqctl list_vhosts
Listing vhosts
/
1
2
3
4
5
6

# 权限授予:set_permissions

AMQP 协议中并没有指定权限在 vhost 级别还是在服务器级别实现,由具体的应用自定义。

在 RabbitMQ 中,权限以 vhost 为单位。在 创建一个用户时,用户通常会被 指派给至少一个 vhost,意味着该用户只能访问被指派的 vhost 内的资源。

授予权限命令为

rabbitmqctl set_permissions [-p vhost] {user} {conf} {write} {read}

参数含义:
 `-p vhost`:给哪一个 vhost 授权用户访问权限
 user:给哪一个用户指定权限
 conf: 用于匹配用户在哪些资源上拥有可配置权限的正则表达式;指:队列和交换器的创建及删除之类的操作
 write:用于匹配用户在哪些资源上拥有可写权限的正则表达式;指:发布消息
 read: 用于匹配用户在哪些资源上拥有可读权限的正则表达式;指:与消息有关的操作,包括读取消息及清空整个队列等
1
2
3
4
5
6
7
8

下表展示了不同 AMQP 命令的列表和对应的权限

AMQP 命令 可配置 可写 可读
Exchange.Declare exchange
Exchange.Declare(with AE) exchange exchange(AE) exchange
Exchange.Delete exchange
Queue.Declare queue
Queue.Declare(with DLX) queue exchange(DLX) queue
Queue.Delete queue
Exchange.Bind exchange(destination) exchange(source)
Exchange.Unbind exchange(destination) exchange(source)
Queue.Bind queue exchange
Queue.Unbind queue exchange
Basic.Publish exchange
Basic.Get queue
Basic.Consume queue
Queue.Purge queue

实践练习:

# 示例 1. 授予 admin 用户可访问虚拟主机 vhost1,并且在所有资源上都具备可配置、可写、可读的权限
# 	 前提是 vhost 要存在
[root@study ~]# rabbitmqctl set_permissions -p vhost1 admin ".*" ".*" ".*"
Setting permissions for user "admin" in vhost "vhost1"

# 示例 2. 授予 admin 可访问虚拟主机 vhost2,在 queue 开头的资源上具备可配置权限,并在所有资源上拥有可写、可读权限
[root@study ~]# rabbitmqctl set_permissions -p vhost2 admin "^queue.*" ".*" ".*"
1
2
3
4
5
6
7

# vhost 权限查看:list_permissions

rabbitmqctl list_permissions [-p vhost]
1

查看虚拟主机上的权限

实践练习:

[root@study ~]# rabbitmqctl list_permissions -p vhost1
Listing permissions in vhost "vhost1"
admin	.*	.*	.*
1
2
3

# 用户权限查看:list_user_permissions

rabbitmqctl list_user_permissions {username}
1

显示用户权限

实践练习:

[root@study ~]# rabbitmqctl list_user_permissions admin
Listing permissions for user "admin"
vhost1	.*	.*	.*
/		.*	.*	.*
1
2
3
4

# 清除权限:clear_permissions

rabbitmqctl clear_permissions [-p vhost] {username}
1

实践练习

[root@study ~]# rabbitmqctl clear_permissions -p vhost1 admin
Clearing permissions for user "admin" in vhost "vhost1"
1
2

# rabbitmqctl 标准语法

上述讲到的管理功能都是通过 rabbitmqctl 来操作的。它通过 连接各个 RabbitMQ 节点来执行所有操作

如果有节点没有运行,将显示诊断信息:不能到达或因不匹配的 Erlang cookie(后续章节:RabbitMQ 运维中讲解)而拒绝连接。

标准语法如下:

rabbitmqctl [-n node] [-t timeout] [-q] {command} [command options...]

参数说明:
	-n node:默认节点是「rabbit@hostname」, hostname 是主机名称。
		     在一个名为「node.hidden.com」的主机上,RabbitMQ 节点的名称通常是 rabbit@node (除非是 RABBITMQ_NODENAME 参数在启动时被设置了自定义的值)
		     在 linux 指令的 `hostname -s` 下,通常输出的就是 @ 后面的信息
	-t timeout:操作超时时间,单位是秒。只适用于 list_xxx 类型的命令,默认无超时
	-q:启用 quiet 模式,可以屏蔽一些消息的输出。默认不开启
	
1
2
3
4
5
6
7
8
9

实践练习:

# 演示 -q 和 -t timeout 的效果
[root@study ~]# rabbitmqctl list_vhosts
Listing vhosts
vhost1
/
[root@study ~]# rabbitmqctl list_vhosts -q
vhost1				# 使用 -q 看到这里少了一列 vhosts 的输出
/
[root@study ~]# rabbitmqctl list_vhosts -q -t 1
vhost1
/
[root@study ~]# rabbitmqctl list_vhosts -q -t 0
Error: {timeout,0.0}
# 这里可以看到超时信息了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15