多租户与权限
每一个 RabbitMQ 服务器都能创建虚拟的消息服务器,我们称之为虚拟主机 (virtual host) , 简称为 vhost。每一个 vhost 本质上是一个独立的小型 RabbitMQ 服务器,拥有自己独立的队列、 交换器及绑定关系等,井且它拥有自己独立的权限。 vhost 就像是虚拟机与物理服务器一样,它们在各个实例间提供逻辑上的分离,为不同程序安全保密地运行数据,它既能将同一个 RabbitMQ 中的众多客户区分开,又可以避免队列和交换器等命名冲突。 vhost 之间是绝对隔离的,无法将 vhostl 中的交换器与 vhost2 中的队列进行绑定,这样既保证了安全性,又可以确保可移植性。如果在使用 RabbitMQ 达到一定规模的时候,建议用户对业务功能、场景进行归类区分,并为之分配独立的 vhost.
vhost 是 AMQP 概念的基础,客户端在连接的时候必须制定一个 vhost. RabbitMQ 默认创建的 vhost 为 "/" , 如果不需要多个 vhost 或者对 vhost 的概念不是很理解,那么用这个默认的 vhost 也是非常合理的,使用默认的用户名 guest 和密码 guest 就可以访问它。但是为了安全和方便,建议重新建立一个新的用户来访问它。
可以使用 rabbitmqctl add_vhost {vhost} 命令创建一个新的 vhost,大括号里的参数表示 vhost 的名称。
示例如下:
root@091f49ee4238:/# rabbitmqctl add_vhost vhost1
Adding vhost "vhost1" ...
root@091f49ee4238:/#
2
3
可以使用 rabbitmqctl list_vhosts [vhostinfoitem...] 来罗列当前 vhost 的相关信息。目前 vhostinfoitem 的取值有 2 个。
- name: 表示 vhost 的名称。
- tracing: 表示是否使用了 RabbitMQ 的 trace 功能。有关 trace 功能,详细可以参考 11.1 节 。
示例如下:
root@091f49ee4238:/# rabbitmqctl list_vhosts name tracing
Listing vhosts ...
name tracing
vhost1 false
/ false
root@091f49ee4238:/# rabbitmqctl trace_on
Starting tracing for vhost "/" ...
Trace enabled for vhost /
root@091f49ee4238:/# rabbitmqctl list_vhosts name tracing
Listing vhosts ...
name tracing
vhost1 false
/ true
root@091f49ee4238:/#
2
3
4
5
6
7
8
9
10
11
12
13
14
对应的删除 vhost 的命令是: rabbitmqctl delete_vhost {vhost) ,其中大括号里面的参数表示 vhost 的名称。删除一个 vhost 同时也会删除其下所有的队列、交换器、绑定关系、用户权限、参数和策略等信息。
示例如下:
root@091f49ee4238:/# rabbitmqctl delete_vhost vhost1
Deleting vhost "vhost1" ...
root@091f49ee4238:/# rabbitmqctl list_vhosts
Listing vhosts ...
name
/
root@091f49ee4238:/#
2
3
4
5
6
7
AMQP 协议中并没有指定权限在 vhost 级别还是在服务器级别实现,由具体的应用自定义。 在 RabbitMQ 中,权限控制则是以 vhost 为单位的 。当创建一个用户时,用户通常会被指派给至少一个 vhost,并且只能访问被指派的 vhost 内的队列、交换器和绑定关系等。因此, RabbitMQ 中的授予权限是指在 vhost 级别对用户而言的权限授予。
相关的授予权限命令为: rabbitmqctl set_permissions [-p vhost] {user} {conf} {write} {read} 。其中各个参数的含义如下所述。
- vhost: 授予用户访问权限的 vhost 名称,可以设置为默认值,即 vhost 为 "/"。
- user: 可以访问指定 vhost 的用户名。
- conf: 一个用于匹配用户在哪些资源上拥有可配置权限的正则表达式。
- write: 一个用于匹配用户在哪些资源上拥有可写权限的正则表达式。
- read: 一个用于匹配用户在哪些资源上拥有可读权限的正则表达式。
注:可配直指的是队列和交换器的创建及删除之类的操作;可写指的是发布消息;可读指 与消息有关的操作,包括读取消息及清空整个队列等。
表 5-1 中 展示了不同 AMQP 命令的列表和对应的权限 。
授予 root 用户可访问虚拟主机 vhost1,并在所有资源上都具备可配置、可写及可读的权限,示例如下:
root@091f49ee4238:/# rabbitmqctl set_permissions -p vhost1 root ".*" ".*" ".*"
Setting permissions for user "root" in vhost "vhost1" ...
root@091f49ee4238:/#
2
3
授予 root 用户可访问虚拟主机 vhost2 , 在以 "queue" 开头的资源上具备可配置权限, 所有资源上拥有可写、可读的权限, 示例如下:
root@81f22c059192:/# rabbitmqctl set_permissions -p vhost2 root "^queue.*" ".*" ".*"
Setting permissions for user "root" in vhost "vhost2" ...
root@81f22c059192:/#
2
3
清除权限也是在 vhost 级别对用户而言的 。清除权限的命令为 rabbitmqctl clear_permissions [-p vhost] {username}。其中 vhost 用于设置禁止用户访问的虚拟主机的名称,默认为 "/"; username 表示禁止访问特定虚拟主机的用户名称。
示例如下:
root@81f22c059192:/# rabbitmqctl clear_permissions -p vhost2 root
Clearing permissions for user "root" in vhost "vhost2" ...
root@81f22c059192:/#
2
3
在 RabbitMQ 中有两个 Shell 命令可以列举权限信息。第一个命令是 rabbitmqctl list_permissions (-p vhost) ,用来显示虚拟主机上的权限;第二个命令是 rabbitmqctl list_user_permissions (username) ,用来显示用户的权限。
示例如下 :
root@81f22c059192:/# rabbitmqctl list_permissions
Listing permissions for vhost "/" ...
user configure write read
guest .* .* .*
root .* .* .*
root@81f22c059192:/# rabbitmqctl list_user_permissions root
Listing permissions for user "root" ...
vhost configure write read
/ .* .* .*
root@81f22c059192:/#
2
3
4
5
6
7
8
9
10
细心的读者可能会注意到本节中用到的所有命令都是 rabbitmqctl 工具的扩展命令, rabbitmqctl 工具是用来管理 RabbitMQ 中间件的命令行工具,它通过连接各个 RabbitMQ 节点来执行所有操作。如果有节点没有运行,将显示诊断信息:不 能到达或因不匹配的 Erlang cookie (有关 Erlang cookie 的细节可以参考 7.1 节) 而拒绝连接。
rabbitmqctl 工具的标准语法如下 ([] 表示可选参数,{} 表示必选参数):
rabbitmqctl [-n node] [-t timeout] [-q] {command} [command options...]
[-n node]
默认节点是 "rabbit@hostname", 此处的 hostname 是主机名称。在一个名为 "node.hidden.com" 的主机上, RabbitMQ 节点的名称通常是 rabbit@node (除非 RABBITMQ_NODENAME 参数在启动时被设置成了非默认值)。hostname -s 命令的输出通常是 "@" 标志后的东西。
[-t timeout]
操作超时时间 (秒为单位),只适用于 "list_xxx" 类型的命令,默认是无穷大。
下面来演示 [-q] 和 [-t timeout] 参数的用法和效果:
root@81f22c059192:/# rabbitmqctl list_vhosts
Listing vhosts ...
name
/
vhost2
root@81f22c059192:/# rabbitmqctl list_vhosts -q
name
/
vhost2
root@81f22c059192:/# rabbitmqctl list_vhosts -q -t 1
name
/
vhost2
root@81f22c059192:/# rabbitmqctl list_vhosts -q -t 0
Error: operation list_vhosts on node rabbit@81f22c059192 timed out. Timeout value used: 0
root@81f22c059192:/#
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16