Jusene's Blog

RabbitMQ管理

字数统计: 4.1k阅读时长: 16 min
2018/02/20 Share

多租户与权限

每一个RabbitMQ服务器都能创建虚拟的消息服务器,称为虚拟主机(virtual host),每一个vhost本质上都是独立的小型RabbitMQ服务器,拥有自己独立的队列、交换机及绑定关系等,并且它拥有自己独立的权限。

vhost是AMQP概念的基础,客户端在连接的时候必须制定一个vhost。RabbitMQ默认创建的vhost是‘/’,默认的用户名guest和密码guest就可以访问它。

创建新的虚拟主机:

1
~]# rabbitmqctl add_vhost vhost1
2
Creating vhost "vhost1" ...
3
...done.
4
~]# rabbitmqctl list_vhosts
5
Listing vhosts ...
6
/
7
vhost1
8
...done.
9
~]# rabbitmqctl delete_vhost vhost1
10
Deleting vhost "vhost1" ...
11
...done.

在rabbitmq中,权限控制权则是以vhost为单位的。当创建一个用户时,用户通常会被指排给至少一个vhost,并且只能访问被指派的vhost内的队列,交换机和绑定关系。

相关的授予权限命令为:
rabbitmqctl set_permissions [-p vhost] {user} {conf}{write}{read}

  • vhost: 授予用户访问权限的vhost名称,可以设置为默认值,即vhost为‘/’
  • user: 可以访问指定vhost的用户
  • conf: 一个用于匹配用户在哪些资源上拥有可配置的正则表达式
  • write: 一个用于匹配用户在哪些资源上拥有可写权限的正则表达式
  • read: 一个用于匹配用户在哪些资源上拥有可读权限的正则表达式

注:可匹配指的是队列和交换机的创建及删除之类的操作,可写指的是发布消息,可读指与消息有关的操作,包括读取消息及清空整个队列等。

1
~]# rabbitmqctl add_user root toor
2
Creating user "root" ...
3
...done.
4
~]# rabbitmqctl set_permissions -p vhost1 root ".*" ".*" ".*"
5
Setting permissions for user "root" in vhost "vhost1" ...
6
...done.
7
~]# rabbitmqctl list_permissions -p vhost1
8
Listing permissions in vhost "vhost1" ...
9
root    .*      .*      .*
10
...done.
11
~]# rabbitmqctl list_user_permissions root
12
Listing permissions for user "root" ...
13
vhost1  .*      .*      .*
14
...done.
15
~]# rabbitmqctl clear_permissions -p vhost1 root
16
Clearing permissions for user "root" in vhost "vhost1" ...
17
...done.

用户管理

在RabbitMQ中,用户是访问控制的基本单元,且单个用户可以跨越多个vhost进行授权。针对一个至多个vhost,用户可以被赋予不同级别的访问权限,并使用标准的用户名和密码来认证用户。

创建用户:
rabbitmqctl add_user {username} {password}

修改密码:
rabbitmqctl change_password {username} {newpassword}

清除密码:
rabbitmqctl clear_password {username}

删除用户:
rabbitmqctl delete_user {username}

查看用户:
rabbitmqctl list_users

设置用户的角色:
rabbitmqctl set_user_tags {username} {tag}

用户的角色分为5种类型:

  • none: 无任何角色,新建的用户的角色默认为none
  • management: 可以访问web管理页面
  • policymarker: 包含management的所以权限,并且可以管理策略和参数
  • monitoring: 包含management的所以的权限,并且可以看到所有连接、信道及节点相关的信息
  • administrator: 包含monitoring的所有权限,并且可以管理用户、虚拟主机、权限、策略、参数等,代表最高权限。

注意:tag参数用于设置0个、1个或者多个角色,设置之后任何之前现有的身份都会被删除。

web端管理

我们可以使用rabbitmqctl工具来管理rabbitmq,但是为了能够运行rabbitmqctl工具,当前用户需要拥有访问erlang cookie的权限,由于服务器是以guest或者root用户身份运行的,因此需要获得这些文件的访问权限,这样就会引申出权限管理的问题。

rabbitmqctl [-n node] [-t timeout] [-q] {command} {command opotions…}

注意:节点不运行,因不可达或不匹配的Erlang cookie而拒绝连接

RabbitMQ management插件可以提供web管理界面用来管理如前面所述的虚拟主机、用户等,也可以用来管理队列、交换机、绑定关系、策略、参数等,还可以用来监控RabbitMQ服务的状态及一些数据统计类信息。启用插件使用rabbitmq-plugin:

rabbitmq-plugins [-n node] {command} {command opotions…}

  • 启用插件:rabbitmq-plugins enable [plugin-name]
  • 关闭插件:rabbitmq-plugins disable [plugin-name]
1
~]# rabbitmq-plugins list
2
[e] amqp_client                       3.3.5
3
[ ] cowboy                            0.5.0-rmq3.3.5-git4b93c2d
4
[ ] eldap                             3.3.5-gite309de4
5
[e] mochiweb                          2.7.0-rmq3.3.5-git680dba8
6
[ ] rabbitmq_amqp1_0                  3.3.5
7
[ ] rabbitmq_auth_backend_ldap        3.3.5
8
[ ] rabbitmq_auth_mechanism_ssl       3.3.5
9
[ ] rabbitmq_consistent_hash_exchange 3.3.5
10
[ ] rabbitmq_federation               3.3.5
11
[ ] rabbitmq_federation_management    3.3.5
12
[E] rabbitmq_management               3.3.5
13
[e] rabbitmq_management_agent         3.3.5
14
[ ] rabbitmq_management_visualiser    3.3.5
15
[ ] rabbitmq_mqtt                     3.3.5
16
[ ] rabbitmq_shovel                   3.3.5
17
[ ] rabbitmq_shovel_management        3.3.5
18
[ ] rabbitmq_stomp                    3.3.5
19
[ ] rabbitmq_test                     3.3.5
20
[ ] rabbitmq_tracing                  3.3.5
21
[e] rabbitmq_web_dispatch             3.3.5
22
[ ] rabbitmq_web_stomp                3.3.5
23
[ ] rabbitmq_web_stomp_examples       3.3.5
24
[ ] sockjs                            0.3.4-rmq3.3.5-git3132eb9
25
[e] webmachine                        1.10.3-rmq3.3.5-gite9359c7

E 为显式启动,e 为显式启动

重启rabbitmq-server,rabbitmq management插件生效,访问http://localhost:15672,rabbitmq web管理界面出现,使用默认的guest账号是访问不了的,在较老的版本中可以访问,但是处于安全考虑,需要一个非none的用户角色的账号来访问web管理界面。

应用与集群管理

应用管理

  • rabbitmqctl stop [pid_file]
    用于停止运行RabbitMQ的Erlang虚拟机和RabbitMQ服务应用,其中pid_file默认情况下存放在Mnesia目录下,可以通过RABBIT_PID_FILE这个环境变量改变存放路径。注意,如果使用rabbitmq-server -detach这个带有-detach后缀的命令来启动RabbitMQ服务不会生成pid_file文件。

  • rabbitmqctl shutdown
    用于停止运行RabbitMQ的Erlang虚拟机和RabbitMQ服务应用,执行这个命令会阻塞直到Erlang虚拟机进程退出,这个命令与rabbitmqctl stop不同的是,它无需要指定pid_file就可以阻塞等待指定进程的关闭。

  • rabbitmq stop_app
    停止RabbitMQ服务应用,但是Erlang虚拟机还是处于运行状态。此命令的执行优先其他管理操作。

  • rabbitmqctl start_app
    启动RabbitMQ应用,此命令典型的用途是在执行了其他管理操作之后,重启之前停止的RabbitMQ应用。

  • rabbitmqctl wait [pid_file]
    等待RabbitMQ应用的启动,他会等待pid_file的创建,然后等待pid_file中所代表的进程启动。

  • rabbitmqctl reset
    将RabbitMQ节点重置还原到最初状态,包括从原来所在的集群中删除此节点,从管理数据库中删除所有的配置数据,如已配置的用户、vhost等,以及删除所以持久化的消息,执行rabbitmqctl reset命令前必须停止RabbitMQ应用。

  • rabbitmqctl force_reset
    强制将RabbitMQ节点重置还原到最初状态,不同于rabbitmqctl reset命令,rabbitmqctl force_reset命令不论当前管理数据库的状态和集群配置是什么,都无条件重置节点,它只在数据库或集群配置已损坏的情况下使用,执行rabbitmqctl force_reset命令前必须停止RabbitMQ应用。

  • rabbitmqctl rotate_log {suffix}
    指示RabbiMQ节点轮换日志文件,RabbitMQ节点会将原来的日志文件中的内容追加到“原始名称+后缀”的日志文件中,然后再将新的日志内容记录到新创建的日志中(与原日志文件同名)。

集群管理

  • rabbitmqctl join_cluster {cluster} [–ram]
    将节点加入指定集群中,在这个命令执行前需要停止RabbitMQ应用并重置节点。

  • rabbitmqctl cluster_status
    显示集群的状态。

  • rabbitmqctl change_cluster_node_type {disc|ram}
    修改集群节点的类型,在这个命令执行前需要停止RabbitMQ应用。

  • rabbitmqctl forget_cluster_node [–offline] {clusternode}
    将节点从集群中删除,允许离线执行。

  • rabbitmqctl update_cluster_nodes {clusternode}
    在集群中的节点应用启动前咨询clusternode节点的最新消息,并更新相应的集群信息。这个和join_cluster不同,它不加入集群。

实例:

1
#初始状态
2
~]# rabbitmqctl cluster_status
3
Cluster status of node rabbit@node1 ...
4
[{nodes,[{disc,[rabbit@INIT]},{ram,[rabbit@node1]}]},
5
 {running_nodes,[rabbit@INIT,rabbit@node1]},
6
 {cluster_name,<<"rabbit@INIT">>},
7
 {partitions,[]}]
8
...done.
9
#关闭node1
10
~]# rabbitmqctl stop_app
11
Stopping node rabbit@node1 ...
12
...done.
13
#之后将node2加入集群
14
~]# rabbitmqctl join_cluster rabbit@INIT
15
#再将INIT节点的应用关闭
16
~]# rabbitmqctl stop_app
17
#最后将node1节点的应用启动,会报错
18
~]# rabbitmqctl start_app
19
#如果在启动node1节点的应用之前咨询node2并更新相关信息则可以解决这个问题
20
~]# rabbitmqctl update_cluster_nodes rabbit@node2
21
#启动node1节点
22
~]# rabbitmqctl start_app
  • rabbitmqctl force_boot
    确保节点可以启动,即使它不是最后一个关闭的节点,通常情况下,当关闭整个RabbitMQ集群时,重启的第一个节点应该是最后关闭的节点,因为它可以看到其他节点所看不到的事情。但是有时也可能出现异常情况,比如整个集群都掉电而所有节点都认为它不是最后一个关闭的,这种情况下,可以调用rabbitmqctl force_boot命令,这就告诉节点可以无条件地启动节点。在此节点关闭后,集群的任何变化,它都会丢失。如果最后一个关闭的节点永久丢失,那么需要优先使用rabbitmqctl forget_cluster_node –offline命令,确保镜像队列正常运转。

  • rabbitmqctl sync_queue [-p vhost] {queue}
    指示未同步队列queue的slave镜像可以同步master镜像的内容,同步期间此队列会被柱塞(所有的生产消费都会备柱塞),直到同步完成。

  • rabbitmqctl cancel_sync_queue [-p vhost] {queue}
    取消队列queue同步镜像的操作。

  • rabbitmqctl set_cluster_name {name}
    设置集群的名称,集群的名称默认是集群中的第一个节点名称。

服务端状态

  • rabbitmqctl list_queues [-p vhost] [queueinfoitem…]
    queueinfoitem:
  1. name: 队列名称
  2. durable: 队列是否持久化
  3. auto_delete: 队列是否自动删除
  4. arguments: 队列的参数
  5. policy: 应用到队列上的策略名称
  6. pid: 队列关联的Erlang进程的ID
  7. owner_pid: 处理排他队列连接的Erlang进程ID,如果此队列是排他性,此值将为空
  8. exclusive: 队列是否排他的
  9. exclusive_consumer_pid: 订阅到此排他队列的消费者相关的信道关联的Erlang进程ID,如果此队列是排他的,此值将为空
  10. exclusive_consumer_tag: 订阅到此排他队列的消费者的consumerTag,如果此队列是排他的,此值为空
  11. messages_ready: 准备发送给客户端的消息个数
  12. messages_unacknowledged: 发送给客户端但尚未应答的消息个数
  13. messages: 准备发送给客户端和未应答消息的总和
  14. messages_ready_ram: 驻留在内存中messages_ready的消息个数
  15. messages_unacknowledged_ram: 驻留在内存中messages_unacknowledged的消息个数
  16. messages_ram: 驻留在内存中的消息总数
  17. messages_persistent: 队列中的持久化消息的个数,对于非持久化的队列来说总是0
  18. messages_bytes: 队列中所有消息的大小总和,这里不包括消息属性或者任何其他开销
  19. messages_bytes_ready: 准备发送给客户端的消息的大小总和
  20. messages_bytes_unacknowledged: 发送给客户端但尚未应答的消息的大小总和
  21. messages_bytes_ram: 驻留在内存中的messages_bytes
  22. messages_bytes_persistent: 队列中持久化的messages_bytes
  23. disk_reads: 从队列启动开始,已从磁盘中读取该队列的消息总次数
  24. disk_write: 从队列启动开始,已向磁盘队列写消息的总次数
  25. consumer: 消费者数目
  26. consumer_utilisation: 队列中消息能够立刻投递给消费者的比率,介于0与1之间
  27. memory: 与队列相关的Erlang进程所消耗的内存
  28. slave_pids: 如果队列是镜像,列出所有slave尽享的pid
  29. synchronised_slave_pids: 如果队列是镜像的,列出所有已经同步的slave镜像的pid
  30. state: 队列状态,正常情况下running
  • rabbitmqctl list_exchange [-p vhost] [exchangeinfoitem …]
    exchangeinfoitem:
  1. name: 交换机的名称
  2. type: 交换机的类型
  3. durable: 设置是否持久化,持久化可以将交换机信息存盘,而在服务器重启的时候不会丢失相关信息
  4. auto_delete: 设置是否自动删除
  5. internal: 是否内置
  6. arguments: 其他一些结构化参数
  7. policy: 应用到交换机上的策略名称
  • rabbitmqctl list_bindings [-p vhost] [bindinginfoitem…]
    bindinginfoitem:
  1. source_name: 绑定中的消息来源的名称
  2. source_kind: 绑定中的消息来源的类型
  3. destination_name: 绑定中消息目的地的名称
  4. destination_kind: 绑定中消息目的地的种类
  5. routing_key: 绑定的路由键
  6. arguments: 绑定的参数
  • rabbitmqctl list_connections [connectioninfoitem…]
    connectioninfoitem:
  1. pid: 与连接相关的erlang进程的id
  2. name: 连接的名称
  3. port: 服务器端口
  4. host: 返回反向DNS获取的服务器主机名称或ip
  5. peer_port: 服务器对端端口,当一个客户端与服务器连接时,这个客户端的端口就是peer_port
  6. peer_host: 返回反向dns获取的对端主机名称或者ip
  7. ssl: 是否启用ssl
  8. ssl_protocol: ssl协议,如tlsv1
  9. ssl_key_exchange: ssl密钥交换算法,如rsa
  10. ssl_cipher: ssl加密算法,如aes_256_cbc
  11. ssl_hash: ssl哈希算法,如sha
  12. peer_cert_subject: 对端的ssl安全证书的主题
  13. peer_cert_issue: 对端ssl安全证书的发行者
  14. peer_cert_validity: 对端ssl安全证书的有效期
  15. state: 连接状态,包括starting,turing,opening,running,flow,blocking,blocked,closing和closed这几种
  16. channels: 该连接中的信道个数
  17. protocol: 使用的AMQP协议的版本
  18. auth_mechainism: 使用的sasl认证机制
  19. user: 与连接相关的用户名
  20. vhost: 与连接相关的vhost的名称
  21. timeout: 连接超时/协商的心跳间隔,单位为秒
  22. frame_max: 最大传输帧的大小
  23. channel_max: 此连接上的信道的最大数量,如果为0表示无上限
  24. client_properties: 在建立连接期间由客户端发送的信息属性
  25. recv_oct: 收到的字节数
  26. recv_cnt: 收到的数据包的个数
  27. send_oct: 发送的字节数
  28. send_cnt: 发送的数据包个数
  29. send_pend: 发送队列大小
  30. connected_at: 连接建立的事件戳
  • rabbitctl list_channels [channelinfoitem…]
    channelinfoitem:
  1. pid: 与连接相关的erlang进程id
  2. connection: 信道所属连接的erlang进程的id
  3. name: 信道的名称
  4. number: 信道的序号
  5. user: 与信道相关的用户名称
  6. vhost: 与信道相关的vhost
  7. transactional: 信道是否处于事物模式
  8. confirm: 信道是否处于publisher confirm模式
  9. consumer_count: 信道中的消费者的个数
  10. message_unacknowledged: 已投递但是还未被ack的消息个数
  11. message_uncommitted: 已接受但是还未提交事务的消息个数
  12. acks_uncommitted: 已ack收到但是还未提交事物的消息个数
  13. message_unconfirmed: 已发送但是还未确认的消息个数
  14. perfetch_count: 新消费者的Qos个数限制,0表示无上限
  15. global_prefetch_count: 整个信道Qos个数限制,0表示无上限
  • rabbitctl list_consumer [-p vhost]
    列举消费者信息,以制表符分隔的已订阅的名称、相关信道的进程标识、consumerTag、是否需要消费端确认、perfetch_count及参数列表这些信息。

  • rabbitctl status
    Broker的状态

  • rabbitctl node_health_check
    对RabbitMQ节点进行健康检查,确认应用是否正常运行、list_queues和list_channels是否能够正常返回。

  • rabbitmq environment
    显示每个运行程序环境中每个变量的名称和值

  • rabbitmqctl report
    为所有服务状态生成一个服务器状态报告,并重定向输出到文件

  • rabbitmqctl eval {expr}
    执行任意erlang表达式

eval扩展

rabbitmqctl实现大多数MQ的操作,但是却无法对交换机、队列及绑定关系的创建(或删除)操作,rabbitmqctl eval {expr}的形式实现rabbitmqctl工具对交换机、队列及绑定关系。

  1. 创建一个交换机
    declare(XName,Type,Durable,AutoDelete,Internal,Args)
    1
    rabbitmqctl eval 'rabbit_exchange:declare({resource,<<"/">>,exchange,<<"exchange2">>},direct,true,false,false,[]).'
  • XName: 交换机的命名细节,具体格式{resource,VHost,exchange,Name}
  • Type: 交换机类型
  • Durable: 是否需要持久化
  • AutoDelete: 是否需要自动删除
  • Internal: 是否是内置的交换机
  • Args: 交换机的一些参数
    删除交换机:
    1
    rabbitmqctl eval 'rabbit_exchange:delete({resource,<<>"/">,exchange,<<"exchange2">>},false).'
  1. 创建一个队列
    declare(QueueName,Durable,AutoDelete,Args,Owner)
    1
    rabbitmqctl eval 'rabbit_amqqueue:declare({resource,<<"/">>,queue,<<"queue2">>},true,false,[],none).'
  • QueueName: 队列的命名细节,具体格式为{resource,VHost,queue,Name}
  • Durable: 是否持久化
  • AutoDelete: 是否自动删除
  • Args: 队列的其他选项参数
  • Owner: 用于队列独占模式,一般为none
    删除队列:
    1
    rabbitmqctl eval 'rabbit_amqqueue:internal_delete({resource,<<"/">>,queue,<<"queue2>>}).'
  1. 绑定关系
    add(Binding)
    1
    rabbitmqctl eval 'rabbit_binding:add({binding,{resource,<<"/">>,exchange,<<"exchange2">>},<<"rk2">>,{resource,<<"/">>,queue,<<"queue2">>},[]}).'
  • Binding: 绑定关系,可以是exchange到exchange,也可以是exchange到queue,具体格式{binding,Source,Key,Destination,Args},Source表示消息源,必须为交换机,Key为路由键,Destination为目的端
    解除绑定关系:
    1
    rabbitmqctl eval 'rabbitmq_binding:remove({binding,{resource,<<"/">>,exchange,<<"exchange2">>},<<"rk2>>,{resource,<<"/">>,queue,<<"queue2">>},[]}).'
CATALOG
  1. 1. 多租户与权限
  2. 2. 用户管理
  3. 3. web端管理
  4. 4. 应用与集群管理
    1. 4.1. 应用管理
    2. 4.2. 集群管理
  5. 5. 服务端状态
    1. 5.1. eval扩展