RabbitMQ(四)管理

RabbitMQ(四)管理

一. 多租户与权限

1.1 什么是vhost?

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

  • 每一个 vhost 本质上是一个独立的小型 RabbitMQ 服务器;
  • 拥有自己独立的队列、交换器及绑定关系等;
  • 井且它拥有自己独立的权限。
  • vhost 之间是绝对隔离的,无法将 vhostl 中的交换器与 vhost2 中的队列进行绑定,既保证了安全性,又可以确保可移植性。
  • 建议用户对业务功能、场景进行归类 区分,并为之分配独立的 vhost。
  • vhost 是 AMQP 概念的基础,客户端在连接的时候必须制定一个 vhost。
  • 默认的 vhost 是 / ,使用默认的用户名 guest 和密码 guest 就可以访问它。

1.2 常用指令

创建新 vhost :

1
2
3
$ rabbitmqctl add_vhost {vhost}
# 示例
$ rabbitmqctl add_vhost vhost1

列表当前所有 vhost :

  • name:vhost名称;
  • tracing:是否使用trace功能。
1
2
3
4
5
6
7
8
9
10
11
12
13
$ rabbitmqctl list_vhosts {vhostinfoitem...}
# 示例
$ rabbitmqctl list_vhosts name tracing
Listing vhosts
vhost1 false
/ false

$ rabbitmqctl trace_on
Starting tracing for host "/"
$ rabbitmqctl list_vhosts name tracing
Listing vhosts
vhost1 false
/ true

删除 vhost :

1
2
3
4
5
6
$ rabbitmqctl delete_vhost {vhost}
# 示例
$ rabbitmqctl delete_vhost vhost1
Deleting vhost "vhost1"
$ rabbitmqctl list_vhosts
Listing vhosts

vhost 授予用户权限:

  • vhost:授予用户权限的vhost名称;
  • user:可以访问vhost的用户名;
  • conf:用于匹配用户在哪些资源上拥有可配置权限的正则表达式(指队列和交换器的创建和删除操作);
  • write:用于匹配用户在哪些资源上拥有可写权限的正则表达式(指发布消息);
  • read:用于匹配用户在哪些资源上拥有可读权限的正则表达式(指与消息有关的操作,如读取消息或清空队列);
1
2
3
4
5
6
7
8
$ rabbitmqctl set_permissions {-p vhost} {user} {conf} {write} {read}
# 示例
# 授予root:可访问vhost1,所有资源可配置 + 可写 + 可读权限
$ rabbitmqctl set_permissions -p vhost1 root ".*" ".*" ".*"
Setting permissions for user "root" in vhost "vhost1"
# 授予root:可访问vhost2,"queue"开头资源上可配置,所有资源可写 + 可读权限
$ rabbitmqctl set_permissions -p vhost2 root "^queue.*" ".*" ".*"
Setting permissions for user "root" in vhost "vhost2"

不同AMQP命令的列表和对应权限:

vhost 清除用户权限:禁止用户访问vhost

1
2
3
4
$ rabbitmqctl clear_permissions {-p vhost} {username}
# 示例
$ rabbitmqctl clear_permissions -p vhost1 root
Clearing permissions for user "root" in vhost "vhost1"

列表查询权限信息:

1
2
3
4
5
6
7
8
9
10
11
12
# 显式虚拟主机上的权限
$ rabbitmqctl list_permissions {-p vhost}
# 显式用户的权限
$ rabbitmqctl list_user_permissions {username}
# 示例
$ rabbitmqctl list_permissions -p vhost1
Listing permissions in vhost "vhost1"
root .* .* .*
$ rabbitmqctl list_user_permissions root
Listing permissions for user "root"
/ .* .* .*
vhost1 .* .* .*

rabbitmqctl 工具是用来管理 RabbitMQ 中间件的命令行工具,它通过连接各个 RabbitMQ 节点来执行所有操作。如果有节点没有运行,将显示诊断信息:不能到达或因不匹配的 Erlang cookie 而拒绝连接。

1
2
# 标准语法
$ rabbitmqctl [-n node] [-t timeout] [-q] {command} [command options]
  • [-n node] :默认节点 rabbit@hostname ,通常 hostname -s 命令输出是 @ 标志后的东西。
  • [-t timeout] :操作超时时间。
  • [-q] :启用quiet模式,可以屏蔽一些消息。

二. 用户管理

在 RabbitMQ 中,用户是访问控制(Access Control) 的基本单元,且单个用户可以跨越多个 vhost 进行授权,同个用户针对多个 vhost 可以被赋予不同级别的访问权限。

2.1 常用指令

创建用户:

1
2
3
4
$ rabbitmqctl add_user {username} {password}
# 示例
$ rabbitmqctl add_user root root123
Creating user "root"

修改密码:

1
2
3
$ rabbitmqctl change_password {username} {newpassword}
# 示例
$ rabbitmqctl change_password root root321

清除密码:

1
2
3
$ rabbitmqctl clear_password {username}
# 示例
$ rabbitmqctl clear_password root

密码验证:

1
2
3
$ rabbitmqctl authenticate_user {username} {password}
# 示例
$ rabbitmqctl authenticate_user root root321

删除用户:

1
2
3
$ rabbitmqctl delete_user {username}
# 示例
$ rabbitmqctl delete_user root

列表查询用户:

1
$ rabbitmqctl list_users

用户包括5种角色类型:

  • none:无任何角色,新用户默认为none。
  • management:允许访问Web管理界面。
  • policymaker:可以管理策略和参数。
  • monitoring:可以看到所有连接、信道及节点的相关信息。
  • administrator:可以管理用户、虚拟主机、权限、策略、参数等。

设置用户角色:

1
2
3
$ rabbitmqctl set_user_tags {username} {tag ...}
# 示例
$ rabbitmqctl set_user_tags root monitoring

三. Web端管理

3.1 RabbitMQ management

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

RabbitMQ 开发了 RabbitMQ management ,由 Erlang 言编写,并且和 RabbitMQ 服务运行在同一个 Erlang 虚拟机中。提供了 Web 管理界面用来管理如前面所述的虚拟主机、用户等,也可以用来管理队列、交换器、绑定关系、策略、 参数等,还可以用来监控 RabbitMQ 服务的状态及一些数据统计类信息,可谓是功能强大,基本上能够涵盖所有 RabbitMQ 管理的功能。

3.2 指令开启和关闭

RabbitMQ插件的默认存放目录:$RABBITMQ_HOME/plugins ,格式为 .ez

1
2
3
4
5
6
# rabbitmq-plugins语法格式
$ rabbitmq-plugins [-n node] {command} [command options...]
# 启动插件
$ rabbitmq-plugins enable [plugin-name]
# 关闭插件
$ rabbitmq-plugins disable [plugin-name]

开启 rabbitmq_management 插件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ rabbitmq-plugins enable rabbitmq_management
Enabling plugins on node rabbit@iZ2zeet6kto8eqx1w7sluzZ:
rabbitmq_management
The following plugins have been configured:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch
Applying plugin configuration to rabbit@iZ2zeet6kto8eqx1w7sluzZ...
The following plugins have been enabled:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch

started 3 plugins.

查看当前插件的使用情况:[E*] 表示显示启动,[e*] 表示隐式启动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$ rabbitmq-plugins list
Listing plugins with pattern ".*" ...
Configured: E = explicitly enabled; e = implicitly enabled
| Status: * = running on rabbit@iZ2zeet6kto8eqx1w7sluzZ
|/
[ ] rabbitmq_amqp1_0 3.8.8
[ ] rabbitmq_auth_backend_cache 3.8.8
[ ] rabbitmq_auth_backend_http 3.8.8
[ ] rabbitmq_auth_backend_ldap 3.8.8
[ ] rabbitmq_auth_backend_oauth2 3.8.8
[ ] rabbitmq_auth_mechanism_ssl 3.8.8
[ ] rabbitmq_consistent_hash_exchange 3.8.8
[ ] rabbitmq_event_exchange 3.8.8
[ ] rabbitmq_federation 3.8.8
[ ] rabbitmq_federation_management 3.8.8
[ ] rabbitmq_jms_topic_exchange 3.8.8
[E*] rabbitmq_management 3.8.8
[e*] rabbitmq_management_agent 3.8.8
[ ] rabbitmq_mqtt 3.8.8
[ ] rabbitmq_peer_discovery_aws 3.8.8
[ ] rabbitmq_peer_discovery_common 3.8.8
[ ] rabbitmq_peer_discovery_consul 3.8.8
[ ] rabbitmq_peer_discovery_etcd 3.8.8
[ ] rabbitmq_peer_discovery_k8s 3.8.8
[ ] rabbitmq_prometheus 3.8.8
[ ] rabbitmq_random_exchange 3.8.8
[ ] rabbitmq_recent_history_exchange 3.8.8
[ ] rabbitmq_sharding 3.8.8
[ ] rabbitmq_shovel 3.8.8
[ ] rabbitmq_shovel_management 3.8.8
[ ] rabbitmq_stomp 3.8.8
[ ] rabbitmq_top 3.8.8
[ ] rabbitmq_tracing 3.8.8
[ ] rabbitmq_trust_store 3.8.8
[e*] rabbitmq_web_dispatch 3.8.8
[ ] rabbitmq_web_mqtt 3.8.8
[ ] rabbitmq_web_mqtt_examples 3.8.8
[ ] rabbitmq_web_stomp 3.8.8
[ ] rabbitmq_web_stomp_examples 3.8.8

还要再重启 RabbitMQ 服务使之生效。

关闭 rabbitmq_management 插件:

1
$ rabbitmq-plugins disable rabbitmq_management

3.3 简单使用图形化工具

注意:阿里云服务器要在管理端配置入方向规则,开放15672端口。

尝试使用 guest 账号登录,但被拦截(如下),只允许本地地址访问。

使用 root 登录:

用户管理可以实现上节所有指令的功能:

可以指定用户角色:

新增了用户 user01

点击一个用户名,进入详情界面:

新用户没有指定虚拟主机,可以设置一个:

注意:有时Web管理界面可以正常登陆,但进入后显式部分页面,这种情况清空一下浏览器缓存即可。

四. 应用与集群管理

4.1 应用管理

停止 Erlang 虚拟机和 RabbitMQ 服务应用:

1
2
3
4
$ rabbitmqctl stop [pid_file]
$ rabbitmqctl shutdown
# 示例
$ rabbitmqctl stop /opt/rabbitmq/var/lib/rabbitmq/mnesia/rabbit\@nodel.pid
  • stop [pid_file]
    • 如果指定了 pid_file, 还需要等待指定进程的结束。
    • pid_file 是通过调用 rabbitmq-server 命令启动 RabbitMQ 服务时创建的,默认情况下存放于 Mnesia 目录中,可以通过 RABBITMQ_PID_FILE 这个环境变量来改变存放路径。
    • 使用 rabbitmq-server -detach 这个带有 -detach 后缀的命令来启动 RabbitMQ 服务则不会生成 pid_file 文件。
  • shutdown
    • 执行这个命令会阻塞直到 Erlang 虚拟机进程退出。
    • 和stop不同的是,不需要指定pid_file即可阻塞等待指定进程的关闭。

停止 RabbitMQ 服务应用:

1
$ rabbitmqctl stop_app
  • 只停止 RabbitMQ 服务应用,Erlang 虚拟机还处于运行状态。

启动 RabbitMQ 服务应用:

1
$ rabbitmqctl start_app

等待 RabbitMQ 应用的启动:

1
2
3
4
$ rabbitmqctl wait [pid_file]
# 示例
$ rabbitmqctl wait
/opt/rabbitmq/var/lib/rabbitmq/mnes a/rabbit\@nodel.pid
  • 等待 pid_file 的创建,和对应进程启动。

重置 RabbitMQ 节点(以及强制重置):

1
2
$ rabbitmqctl reset
$ rabbitmqctl force_reset
  • 重置操作将节点还原至最初状态。
    • 从所在集群删除此节点
    • 从管理数据库中删除所有配置数据,如已配置的用户、vhost等
    • 删除所有持久化消息。
  • 重置前要先停止 RabbitMQ 应用。
  • 强制重置不同的是不会考虑集群和管理数据库的状态

指示 RabbitMQ 节点轮换日志文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ rabbitmqctl rotate_logs {suffix}
# 示例
$ pwd
/opt/rabbitmq/var/log/rabbitmq
$ ll
-rw-r--r-- 1 root root 1024127 Oct 18 11:56 rabbit@node1.log
-rw-r--r-- 1 root root 720553 Oct 17 19:16 rabbit@node1-sasl.log
# 原日志文件为 rabbit@node1.log 和 rabbit@node1-sasl.log
$ rabbitmqctl rotate_logs .1
Rotating logs to files with suffix ".1"
# 轮换日志之后,原日志文件中的内容就被迫加到 rabbit@nodel.log.1 rabbit@node1-sasl.log.1 日志中
$ ll
-rw-r--r-- 1 root root 0 Oct 18 12:05 rabbit@node1.log
-rw-r--r-- 1 root root 1024202 Oct 18 12:05 rabbit@node1.log.1
-rw-r--r-- 1 root root 0 Oct 18 12:05 rabbit@node1-sasl.log
-rw-r--r-- 1 root root 720553 Oct 18 12:05 rabbit@node1-sasl.log.1
# 之后重新建立 rabbit@node1.log 和 rabbit@node1-sasl.log 文件用来接收新的日志。
  • 将原日志文件的内容追加到“原始名称+后缀”的日志文件中;
  • 将新日志内容记录到新创建的日志中(同名),不存在会创建文件;
  • 若不指定后缀,只会打开文件而不进行轮换。

将 RabbitMQ 代码用 HiPE 编译,生成的 .beam 文件保存到指定文件目录:

1
2
3
4
5
6
7
$ rabbitmqctl hipe_compile {directory}
# 示例
$ rabbitmqctl hipe compile
/opt/rabbitmq/tmp/rabbit-hipe/ebin
HiPE compiling: |-----------------------------------------------|
|###############################################|
Compiled 57 modules in 55s
  • 如果要使用预编译的这些文件,则需要设置 RABBITMQ_SERVER_CODE_PATH 这个环境变量来指定 hipe_compile 调用的路径。

4.2 集群管理

将节点加入指定集群中:(在这个命令执行前需要停止 RabbitMQ 应用并重置节点)

1
$ rabbitmqctl join_cluster {cluster_node} [--ram] 

显式集群的状态:

1
$ rabbitmqctl cluster_status

修改集群节点的类型:(在这个命令执行前需要停止 RabbitMQ 应用)

1
$ rabbitmqctl change_cluster_node_type {disc|ram}

将节点从集群中删除,允许离线执行:

1
$ rabbitmqctl forget_cluster_node [--offline] 

在集群中的节点应用启动前咨询 clusternode 节点的最新信息,并更新相应的集群信息:

1
$ rabbitmqctl update_cluster_nodes {clusternode} 
  • 和 join_cluster 不同 ,它不加入集群。

  • 使用案例:考虑这样一种情况,节点A和节点B都在集群 中,当节点A离线了,节点C又和节点B组成了一个集群,然后节点B又离开了集群,当A醒来的时候,它会尝试联系节点B但是这样会失败,因为节点B经不在集群中了。 Rabbitmqctl update_cluster_nodes -n A C 可以解决这种场景下出现的问题。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    ## 假设己有 node1 和 node 组成的集群
    ## 1. 初始状态
    $ rabbitmqctl cluster_status
    [
    {nodes, [{disc , [rabbit@node1, rabbit@node2]}]
    },
    {running_nodes, [rabbit@node2, rabbit@node1]},
    {cluster_name, <<"rabbit@node1">>},
    {partitions, []},
    {alarms, [
    {rabbit@node2, []},
    {rabbit@node1, []}
    ]
    }
    ]
    ##2. 关闭 node1 节点的应用
    $ rabbitmqctl stop_app
    ##3. 之后将 node3 加入到集群中
    $ rabbitmqctl join_cluster rabbit@node2
    ##4. 再将 node2 节点的应用关闭
    ##5. 最后启动 node1 节点的应用,此时会报错
    $ rabbitmqctl start_app
    Starting node rabbit@node1
    BOOT FAILED
    ==========
    Timeout contacting cluster nodes : [rabbit@node2] .
    ......
    ##6. 如果在启动 node1 节点的应用之前咨询 node3 并更新相关集群信息则可以解决这个问题
    $ rabbitmqctl update_cluster_nodes rabbit@node3
    Updating cluster nodes for rabbit@node1 from rabbit@node3
    $ rabbitmqctl start_app
    Starting node rabbit@node1
    ##7. 查看最终集群状态
    $ rabbitmqctl cluster_status

确保节点可以启动,即使它不是最后一个关闭的节点:

1
$ rabbitmqctl force_boot 
  • 通常情况下,当关闭整个 RabbitMQ 集群时,重启的第一个节点应该是最后关闭的节点,因为它可以看到其他节点所看不到的事情。
  • 有时会有一些异常情况出现,比如整个集群都掉电而所有节点都认为它不是最后关闭 的。
  • 这时可以调用 rabbitmqctl force_boot 命令,告诉节点可以无条件地启动节点 。在此节点关闭后,集群的任何变化,它都会丢失。
  • 如果最后一个关闭的节点永久 丢失了,那么需要优先使用 rabbitmqctl forget_cluster_node --offline 命令,因 为它可以确保镜像队列的正常运转。

指示未同步队列 queue 的 slave 镜像可以同步 master 镜像行的内容:

1
$ rabbitmqctl sync_queue [-p vhost] {queue} 
  • 同步期间此队列会被阻塞(所有此队列的生产消费者都会被阻塞),直到同步完成。
  • 执行成功的前提是队列 queue 配置了镜像。
  • 未同步队列中的消息被耗尽后,最终也会变成同步,此命令主要用于未耗尽的队列。

取消队列 queue 同步镜像的操作:

1
$ rabbitmqctl cancel_sync_queue [-p vhost] {queue} 

设置集群名称:

1
$ rabbitmqctl set_cluster_name {name} 
  • 集群名称在客户端连接时会通报给客户端。
  • 默认是集群中第一个节点的名称。

五. 服务端状态

服务器状态的查询会返回一个以制表符分隔的列表,此类命令接受一个可选 vhost 参数以显示其结果, 默认值为 /

  • list_queues
  • list_exchanges
  • list_bindings
  • list_consumers

5.1 list_queues

此命令返回队列的详细信息:

1
$ rabbitmqctl list_queues [-p vhost] [queueinfoitem ...] 

queueinfoitem 参数用于指示哪些队列的信息项会包含在结果集中,结果集的列顺序将匹配参数的顺序,取值可以是:

  • name :队列名称。
  • durable :队列是否持久化。
  • auto_delete :队列是否自动删除。
  • arguments :队列的参数。
  • policy :应用到队列上的策略名称。
  • pid:队列关联的 Erlang 进程的 ID。
  • owner_pid :处理排他队列连接的 Erlang 进程。如果此队列是非排他的,此值将为空。
  • exclusive :队列是否是排他的。
  • exclusive_consumer_pid :订阅到此排他队列的消费者相关的信道关联的 Erlang 进程。如果此队列是非排他的,此值将为空。
  • exclusive_consumer_tag :订阅到此排他队列的消费者的 consumerTag 如果此队列是非排他的,此值将为空。
  • messages_ready :准备发送给客户端的消息个数。
  • messages_unacknowledged :发送给客户端但尚未应答的消息个数。messages :准备发送给客户端和未应答消息的总和。
  • messages_ready_ram :驻留在内存中 messages_ready 的消息个数。
  • messages_unacknowledged_ram :驻留在内存中。messages_unacknowledged 的消息个数。
  • messages ram :驻留在内存中的消息总数。
  • messages_persistent :队列中持久化消息的个数,对于非持久化队列来说总是0。
  • messages_bytes :队列中所有消息的大小总和。不包括消息属性或者任何其他开销。
  • messages_bytes_ready :准备发送给客户端的消息的大小总和。
  • messages_bytes_unacknowledged :发送给客户端但尚未应答的消息的大小总和。
  • messages_bytes_ram:驻留在内存中的 messages_bytes。
  • messages_bytes_persiste :队列中持久化的 messages_bytes。
  • disk_reads :从队列启动开始,己从磁盘中读取该队列的消息总次数。
  • disk_writes :从队列启动开始,己向磁盘队列写消息的总次数。
  • consumer :消费者数目。
  • consumer_utilisation :队列中的消息能够立刻投递给消费者的比率,介于0或1之间 。这个受网络拥塞或者 Basic.Qos 的影响而小于1。
  • memory :与队列相关的 Erlang 进程所消耗的内存字节数,包括栈、堆及内部结构。
  • slave_pids :如果队列是镜像的,列出所有 slave 镜像的 pid。
  • synchronised_slave_pids :如果队列是镜像的,列出所有己经同步的 slave 镜像 pid。
  • state :队列状态。正常情况下是 running ;如果队列正常同步数据可能会有 {syncing, MsgCount} 的状态;如果队列所在的节点掉线了,则队列显示状态为 down (此时大多数的 queueinfoitems 也将不可用)。

如果没有指定 queueinfoitems ,那么此命令将显示队列的名称和消息的个数。

5.2 list_exchanges

返回交换器的详细细节:

1
$ rabbitmqctl list_exchanges [-p vhost] [exchangeinfoitem ...] 

exchangeinfoitem 参数用于指示哪些信息项会包含在结果集中,结果集的列顺序将匹配参数的顺序,取值可以是:

  • name :交换器的名称。
  • type :交换器的类型。
  • durable :设置是否持久化。 durable 设置为 true 表示持久化,反之是非持久化。持久化可以将交换器信息存盘而在服务器重启的时候不会丢失相关信息。
  • auto_delete :设直是否自动删除。
  • internal :是否是内置的。
  • arguments :其他一些结构化参数,比如 alternate-exchange
  • policy :应用到交换器上的策略名称。

exchangeinfoitem 的内容和客户端中的 channel.exchangeDeclare 方法的参数基本一致。

5.3 list_bindings

返回绑定关系的细节:

1
$ rabbitmqctl list_bindings [-p vhost] [bindinginfoitem ...] 

bindinginfoitem 参数用于指示哪些信息项会包含在结果集中,结果集的列顺序将匹配参数的顺序,取值可以是:

  • source_name :绑定中消息来源的名称。
  • source_kind :绑定中消息来源的类别。
  • destination_name :绑定中消息目的地的名称。
  • destination_kind :绑定中消息目的地的种类。
  • routing_key :绑定的路由键。
  • arguments :绑定的参数。

5.4 list_connections

返回 TCP/IP 连接的统计信息:

1
$ rabbitmqctl list_connections [connectioninfoitem ...] 

connectioninfoitem 参数用于指示哪些信息项会包含在结果集中,结果集的列顺序将匹配参数的顺序,取值可以是:

  • pid :与连接相关的 Erlang 进程 ID
  • name :连接的名称。
  • port :服务器端口。
  • host :返回反向 DNS 获取的服务器主机名称,或者 IP 地址,或者未启用。
  • peer_port :服务器对端端口。当一个客户端与服务器连接时,这个客户端的端口就是 peer_port 。
  • peer_host :返回反向 DNS 获取的对端主机名称,或者 IP 地址, 或者未启用。
  • ssl :是否启用 SSL 。
  • ssl_protocol :SSL 协议,如 tlsvl 。
  • ssl_key_exchange :SSL 密钥交换算法,如 rsa 。
  • ssl_cipher :SSL 加密算法,如 aes_256_cbc 。
  • ssl_hash :SSL 哈希算法,如 sha 。
  • peer_cert_subject :对端的 SSL 安全证书的主题,基于 RFC4514 的形式。 peer_cert_issuer :对端 SSL 安全证书的发行者, 基于 RFC4514 的形式。
  • peer_cert_validity :对端 SSL 安全证书的有效期。
  • state :连接状态,包括 starting、tuning、opening、running、flow、blocking、blocked、closing、closed 这几种。
  • channels :该连接中的信道个数。
  • protocol :使用的 AMQP 协议的版本,当前是{0,9,1}或者{0,8,0}。注意,如果客户端请求的是 AMQP 0-9 的连接, RabbitMQ 也会将其视为 0-9-1 。
  • auth_mechanism :使用的 SASL 认证机制,如 PLAIN、AMQPLAIN、EXTERNAL、RABBIT-CR-DEMO 等。
  • user :与连接相关的用户名。
  • vhost :与连接相关的 vhost 的名称。
  • timeout :连接超时/协商的心跳间隔,单位为秒。
  • frame_max :最大传输帧的大小,单位为 B 。
  • channel_max :此连接上信道的最大数量。如果值 0,则表示无上限,但客户端一般会将0转变为 65535 。
  • client_properties :在建立连接期间由客户端发送的信息属性。
  • recv_oct :收到的字节数。
  • recv_cnt :收到的数据包个数。
  • send_oct :发送的字节数。
  • send_cnt :发送的数据包个数。
  • send_pend :发送队列大小。
  • connected_at :连接建立的时间戳。

5.5 list_channels

返回当前所有信道的信息:

1
$ rabbitmqctl list_channels [channelinfoitem ...] 

channelinfoitem 参数用于指示哪些信息项会包含在结果集中,结果集的列顺序将匹配参数的顺序,取值可以是:

  • pid :与连接相关的 Erlang 进程 ID 。
  • connection :信道所属连接的 Erlang 进程 ID 。
  • name :信道的名称。
  • number :信道的序号。
  • user :与信道相关的用户名称。
  • vhost :与信道相关的 vhost 。
  • transactional :信道是否处于事务模式。
  • confirm :信道是否处于 publiser confirm 模式。
  • consumer_count :信道中的消费者的个数。
  • messages_unacknowledged :已投递但是还未被 ack 的消息个数。
  • messages_uncommitted :已接收但是还未提交事务的消息个数。
  • acks_uncommitted :已 ack 收到但是还未提交事务的消息个数。
  • messages_unconfirmed :已发送但是还未确认的消息个数。如果信道不处于 publisher confirm 模式下,则此值为 0 。
  • perfetch_count :新消费者的 Qos 个数限制,0 表示无上限。
  • global_prefetch_count :整个信道的 Qos 个数限制,0 表示无上限。

5.6 list_consumers

列举消费者信息:

1
$ rabbitmqctl list_consumers [-p vhost]

每行将显示由制表符分隔的己订阅队列的名称、相关信道的进程标识、 consumerTag、是否需要消费端确认、 prefetch_count 及参数列表这些信息。

5.7 其它

显示 Broker 状态,比如当前 Erlang 节点上运行的应用程序、RabbitMQ/Erlang 的版本信息、 OS 的名称、内存及文件描述符等统计信息:

1
$ rabbitmqctl status 

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

1
$ rabbitmqctl node_health_check 

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

1
$ rabbitmqctl environment 

为所有服务器状态生成一个服务器状态报告,井将输出重定向到一个文件:

1
$ rabbitmqctl report 

执行任意 Erlang 表达式:(此处暂时不作eval扩展)

1
$ rabbitmqctl eval {expr} 

六. HTTP API接口管理

6.1 HTTP API接口功能

RabbitMQ Management 插件不仅提供了 Web 管理界面,还提供了 HTTP API 接口来方便调用。比如创建一个队列,就可以通过 PUT 方法调用 /api/queues/vhost/name 接口来实现。

1
2
3
4
5
6
7
8
9
10
$ curl -i -u root:root123 -H "content-type:application/json"
-XPUT -d '{"auto_delete":false,"durable":true,"node":"rabbit@node2"}'
http://192.168.0.2:15672/api/queues/%2F/queue

HTTP/1.1 201 Created
server: Cowboy
date: Fri, 25 Aug 2017 06:03:17 GMT
content-length: 0
content-type: application/json
vary: accept, accept-encoding, origin

%2F/ 默认的 vhost,特殊字符需要在HTTP URL中进行转义。

完全基于 RESTful 风格:

  • GET 方法一般用来获取如集群、节点、队列、交换器等信息。
  • PUT 方法用来创建资源,如交换器、队列之类的。
  • DELETE 方法用来删除资源。
  • POST 方法也是用来创建资源的,与 PUT 不同的是,POST 创建的是无法用具体名称的资源。比如绑定关系(bindings)和发布消息(publish)无法指定一个具体的名称。

6.2 接口列表

GET PUT DELETE POST Path & Description
X /api/overview
描述整个系统的各种信息
X X /api/cluster-name
集群的名称
X /api/nodes
集群中节点的信息
X /api/nodes/name
集群中单个节点的信息
X /api/extensions
管理插件的扩展列表
X X /api/definitions
GET 方法列出集群中所有的元数据信息,包括交换器、队列、绑定关系、用户、 host 权限及参数。
POST 方法用来加载新的元数据信息,不过需要注意如下内容:
(1)新的原数据信息会与原本的合并,如果旧的元数据信息中某些项在新加载的 元数据中没有定义, 则不受任何影响
(2)对于交换器、队列及绑定关系等不可变的内容,如果新旧元数据有冲突,则会报错
(3)对于其他的可变的内容,如果新旧元数据有冲突,则新的会替换旧的
(4)如果在加载过程中发生错误,加载过程会停止,最终只能加载到部分新的元数据信息
X X /api/definitions/vhost
将/api/definitions 接口细化到 vhost 级别,其余内容同上
X /api/connections
所有的连接信息
X /api/vhosts/vhost/connections
指定的 vhost 中所有连接信息
X X /api/connections/name
GET 方法列出指定连接的信息
DELETE 方法可以 close 指定的连接
X /api/connections/name/channels
指定连接的所有信道信息
X /api/channels
所有信道的信息
X /api/vhosts/vhost/channels
指定的 vhost 中所有信道信息
X /api/channels/channel
指定的信道信息
X /api/consumers
所有的消费者信息
X /api/consumers/vhost
指定 vhost 中的所有消费者信息
X /api/exchanges
所有交换器信息
X /api/exchanges/vhost
指定 vhost 中所有交换器信息
X X X /api/exchanges/vhost/name
GET 方法列出一个指定的交换器信息。
PUT 方法可以声明一个交换器,对应的内容可以参考如下:
{“type”:”direct”,”auto_ delete”:false,”durable”:true ,”internal”:false,”arguments”:{}}
其中 type 是必需的,其他都是可选的。
DELETE 方法可以删除指定的交换器,其中可以添加 if-unused=true 参数用来防止有队列与其绑定时能够被删除
X /api/exchanges/vhost/name/bindings/source
列出指定交换器的所有绑定关系,此交换器需为绑定关系的源端
X /api/exchanges/vhost/name/bindings/destination
列出指定交换器的所有绑定关系,此交换器帘为绑定关系的目的端
X /api/exchanges/vhost/name/publish
向指定的交换器中发送一条消息,对应的内容可以参考:
{“properties”:{},”routing_key”,”my key”,”payload:”my body”,”payload_ encoding”:”string”}
这里所有的项都是必需的,如果发送成功,会返回 {”routed”:true} 。这个接口不适合做稳定、高效的发送之用 ,以采用其他的方式比如通过 AMQP 协议或者其他长连接的协议
X /api/queues
列出所有的队列信息
X /api/queues/vhost
列出指定的 vhost 下所有的队列信息
X X X /api/queues/vhost/name
GET 方法列出执行的队列信息
PUT 方法可声明一个队列,对应的内容可以参考:
{“auto_delete”:false,”durable”:true,”arguments”:{},”node”:”rabbit@smacmullen”}
其中所有的项都是可选的。
DELETE 方法用来删除一个队列,当然可以指定 if-empty 或 if-unused 参数
X /api/queues/vhost/name/bindings
列出指定队列的所有绑定关系
X /api/queues/vhost/name/contents
清空(purge)指定的队列
X /api/queues/vhost/name/actions
对指定的队列附加一些动作,对应的内容可以参考:
{“action”:”sync”}
目前仅支持 sync 和 cancel_sync
X /api/queues/vhost/name/get
从指定队列中获取消息,对应的内容可以参考:
{“count”:5,”requeue”:true,”encoding”:”auto”,”truncate”:50000}
count 表示最大能获取的消息个数,实际可能小于这个值;requeue 表示获取到这些消息时是否从队列中删除,如果 requeue 为 true ,则消息不会被删除,但是消息的 redelivered 标示会被设置;encoding 表示编码格式,两种取值:auto 和 base64,auto 指如果消息符合 UTF-8 格式则返回 string 类型,否则为 base64 类型; truncate表示如果消息的 payload 过指定大小会被截断。除了 truncate 其余项都是必需的。注意这个接口是用来做测试用的,如果要持续的消费队列的消息,需要采用其他的方法
X /api/bindings
列出所有绑定关系的信息
X /api/bindings/vhost
列出指定的 vhost 中所有绑定关系的信息
X X /api/bindings/vhost/e/exchange/q/queue
GET 方法列出一个指定的交换器和一个指定的队列中的所有绑定关系的信息。注意一个交换器和一个队列之间可以绑定多次.。
POST 用来添加绑定关系,对应的内容可以参考:
{“routing_ key”:”my_routing_ key”,”arguments”:{}} 其中所有的项都是可选的
X X /api/bindings/vhost/e/exchange/q/queue/props
GET 方法列出一个交换器和一个队列的一个单独的绑定关系的信息
DELETE 方法用来解绑相应的绑定关系,其中 props 表示的是 /api/bindings 返回的绑定关系列表里的 properties_key 的值,具体是指绑定时 routingkey 与 arguments 的哈希值的组合,一般 arguments 为空,此时 properties_key 等于 routingkey
X X /api/bindings/vhost/e/source/e/destination
GET 方法用来列出两个交换器的所有绑定关系的信息
POST 方法用来添加绑定关系,与接口 /api/bindings/vhost/e/exchange/q/queue 相似
X X /api/bindings/vhost/e/source/e/destination/props
与接口/api/bindings/vhost/e/exchange/q/queue/props 相似,只不过是两个交换器之间的关系
X /api/vhosts
列出所有 vhost 的信息
X X X /api/vhosts/name
GET 方法列出指定 vhost 的信息
PUT 方法用来添加 vhost,host 通常只有一个名字,所以不需要任何内容以做请求之用。
DELETE 方法用来删除 vhost
X /api/vhosts/name/permissions
列出指定 vhost 的所有权限信息
X /api/users
列出所有的用户信息
X X X /api/users/name
GET 方法列出指定的用户信息
POST 方法用来添加一个用户,对应的内容参考:
{“password”:”secret”,”tags”:”administrator”}
或者
{“password_hash”:”2lmotb814HODViLaK9Fxi619ds8=”,”tags”:”administrator”}
其中 tags 是必需的,用来标识用户角色。对于 password 或者 password_hash,两者可以择其一。 如果 password_hash 为“”,则用户可以无密码登录。
DELETE 方法用来删除指定的用户
X /api/users/user/permissions
用来获取指定用户的所有权限
X /api/wboami
当前的登录用户
X /api/perrnissions
列出所有用户的所有权限
X X X /api/permissions/vhost/user
GET 方法列出指定的权限
PUT 方法添加指定的权限,对应的内容惨考:
{“configure”:”.*“,”write”:”.*“,”read”:”.*“}
所有项都是必需的,对应 configure、write、read 的细节可以参考 5.1节
DELETE 方法用来删除指定的权限
X /api/parameters
列出所有 vhost 级别的 Parameter
X /api/parameters/component
列出指定组件(比如 federation-upstream、shovel 等)的所有 vhost 级别的 Parameter
X /api/parameters/component/vhost
列出指定 vhost 和组件的所有 vhost 级别的 Parameter
X X X /api/parameters/component/vhost/name
GET 方法列出一个指定的 vbost 级别的 Parameter
PUT 方法用来设置一个 Parameter ,对应的内容参考如下:
{“vhost”:”/“,”component”:”federation”,”name”:”local_username”,”value”:”guest”}
DELETE 方法用来删除一个指定的 vhost 级别的 Parameter
X /api/global-parameters
列出所有的 global 级别的 Parameter
X X X /api/global-parameters/name
GET 方法列出一个指定的 global 级别的 Parameter
PUT 方法用来设置一个指定的 global 级别的 Parameter,对应的内容参考:
{“name”:”user_ vhost_mapping”,”value”:{“guest”:”/“,”rabbit”:”warren”}}
DELETE 方法用来删除一个指定的 global 级别的 Parameter
X /api/policies
列出所有的 Policy
X /api/policies/vhost
列出指定 vhost 下的所有 Policy
X X X /api/policies/vhost/name
GET 方法列出指定的 Policy
PUT 方法用来设置 Policy 对应的内容可以参考:
{“pattern”:”^amq.”,”definition”: {“federation-upstream-set”:”all”}, “priority”:0, “apply-to”:”all”}
其中 pattern 和 definition 是必需的,其余可选。
DELETE 方法用来删除一个指定的 Policy
X api/aliveness-test/vhost
声明一个队列,并基于其上生产和消费一条消息,用来测试系统是否运行完好。这个接口可以方便一些监控工具〈如 Zabbix )的调用。如果系统运行完好,调用这接口会返回 {“status”:”ok”},状态码为 200
X /api/healthchecks/node
对当前节点中进行基本的健康检查,包括 RabbitMQ 应用、信道、队列是否正常运行且无告警。如果一切正常则接口返回:
{“status”:”ok”}
如果有异常则接口返回:
{“status”:”failed”,”reason”,”string”}
不管正常与否,状态都是 200
X /api/healthchecks/node/node
对指定节点进行基本的健康检查,其余同 /api/healthchecks/node

创建、显示和删除队列 queue 可以这样实现:

1
2
3
4
5
6
7
8
9
10
11
12
$ ./rabbitmqadmin -u root -p rootl23 declare queue name=queue1
queue declared
$ ./rabbitmqadmin list queues
+--------+----------+
| name | messages |
+--------+----------+
| queue1 | 0 |
+--------+----------+
$ ./rabbitmqadmin -u root -p rootl23 delete queue name=queue1
queue deleted
$ ./rabbitmqadmin list queues
No items

rabbitmqadmin 需要安装,可以通过Web管理界面左下角 【Command Line】进行下载,或者如下指令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ wget http://192.168 0.2:15672/cli/rabbitmqadmin
--2017-08-25 17:32:50-- http://192.168.0.2:15672/cli/rabbitmqadmin
Connecting to 192.168.0.2:15672 ... connected.
HTTP request sent, awaiting response ... 200 OK
Length: 36192 (35K) [application/octet-stream]
Saving to "rabbitmqadmin"
100%[================================>] 36,192 --.-K/s .in 0s
2017-08-25 17:32:50 (372 MB/s) - "rabbitmqadmin" saved [36192/36192]
$ chmod +x rabbitmqadmin
# 确保已安装python
$ python
......
# 获取使用方式
$ ./rabbitmqadmin --help

参考:

🔗 《RabbitMQ实战指南》