[翻译]RabbitMQ 的 Management Plugin 插件
Contents
介绍
rabbitmq-management 插件提供了基于 HTTP 的API来管理及监控你的 RabbitMQ 服务器,以及基于浏览器的UI和命令工具 rabbitmqadmin 。功能包括:
- 声明,列出和删除交换机、队列、绑定、用户、虚拟主机和权限
- 监控队列长度、全局和每个Channel的消息速率、每条连接的数据速率,等等
- 监控资源使用,例如:文件描述符、内存使用、可用磁盘空间
- 管理用户(要求当前用户具有管理员身份的权限)
- 导出和导入对象定义(虚拟机、用户、权限、队列、交换机、绑定、参数、策略)到 JSON
- 强制关闭连接(connection)、清除队列消息(purge queues)
- 发送和接收消息(对于开发环境以及分析解决问题比较有用)
开始
management plugin 插件是包含在 RabbitMQ 发行版中的。为了开启它,使用 rabbitmq-plugins:
rabbitmq-plugins enable rabbitmq_management
Web界面的地址在: http://server-name:15672/
在插件里Web界面同样使用该插件来提供一个 HTTP API 。查看 API 文档可以访问: http://server-host:15672/api/ 或者我们 这里最新的 HTTP API 文档
注意,在 RabbitMQ 3.0 版本之前的端口为 55672.
为了使用 Web 界面你需要使用 RabbitMQ 用户来进行身份认证(新安装的时,用户名为 *guest*,密码为 *guest*)。在这里,你可以管理交换机、队列、绑定、虚拟主机、用户和权限。希望界面是自解释的。
management 的界面的实现是单个静态HTML页面的,它使用后台查询 HTTP API 。因此,它大量使用 JavaScript。它已经在最近版本的 Firefox、Chromium 和 Safari 测试过了,并且也回归测试过了 IE 6.0
权限 management < policymaker < monitoring < administrator
management 插件有些扩展了现有的权限模型。在RabbitMQ中,可以给定用户任意标签。 management 插件使用名为 management 、 policymaker 、 monitoring 和 administrator 的标签。下表显示了不同类型的用户可以做些什么:
标签为:空
不能访问 management 插件
标签为:management
可以做的事有:
- 列出所有可以通过 AMQP 登录的虚拟主机
- 在 它们 所在的虚拟主机中,查看所有队列、交换机和绑定
- 查看和关闭它们各自的 Channel 和 Connections
- 查看覆盖它们自己所有虚拟主机的 全局 统计信息,包括其他用户在这些虚拟机主内的活动
标签为:policymaker
所有 management 可以做的,加上下面:
查看、创建和删除可以通过 AMQP 登录的虚拟主机的策略和参数
标签为: monitoring
所有 management 可以做的,加上下面:
- 队列所有虚拟主机,包括无法通过 AMQP 登录的虚拟机主机
- 查看其他用户的 connection 和 channel
- 查看节点级别数据,比如:内存使用和集群
- 查看所有虚拟主机真实的全局统计信息
标签为: administrator
所有 policymaker 和 monitoring 可以做的,加上:
- 创建和删除虚拟主机
- 查看、创建和删除用户
- 查看、创建和删除权限
- 关闭其他用户的 connection
注意,由于 administrator 可以做所有 monitoring 的事,而 monitoring 可以做所有 management 可做的事,因此你通常只需要为每个用户提供最多一个标签即可。
后续
正常的 RabbitMQ 权限仍然适用于 monitors 和 administrators ;只是因为用户是一个 monitor 或 administrator 并不能通过 AMQP 或 management plugin 插件给它们完全访问交换机、队列和绑定。
如果由于只有 non-administrator 用户或根本没有用户而被锁定,你可以使用 rabbitmqctl add_user 来创建一个 non-administrator 用户,然后使用 rabbitmqctl set_user_tags 来提升它为 administrator
HTTP API
management plugin 插件会创建一个基于 HTTP 的API在 http://server-name:15672/api/ ,浏览该地址可以获取有关API的更多信息。为了方便起见,你可以在 Github 中阅读 最新HTTP API文档
可以在启用了 rabbitmq-management 插件的任何节点上使用 HTTP API 。然后它能够提供在集群节点中一个或所有节点的测量信息。当监视节点集群时,不需要单独通过 HTTP API 与每个节点进行联系。相反,联系随机一个节点或集群中负载均衡器前端即可。
对于多种语言的 HTTP API 客户端,请参阅 开发者工具
rabbitmqadmin 是一个 Python 的与HTTP API 交互的命令行工具。它可以从任意的开启了 management plugin 的RabbitMQ节点中下载,地址为: http://server-name:15672/cli/
配置
这时有几个影响 management plugin 插件的配置选项。它们是通过 RabbitMQ 主配置文件 进行管理的.
启动时加载定义
management plugin 插件允许你导出所有包含 Broker 对象(队列、交换机、绑定、用户、虚拟主机、权限和参数)定义的JOSN文件。在某些情况下,确定在启动时都存在这些对象可能是有用的。
为此,请将 rabbitmq_management.load_definitions 的配置项,指向你先前导出的JSON文件的路径:
[
{rabbitmq_management, [
{load_definitions, "/path/to/definitions/file.json"}
]}
].
注意,文件中的定义将会覆盖现存在 Broker 中的所有内容。使用这个选项并不会删除任何已经存在的内容。但是,如果从完全重置的 Broker 中开始的话,使用这个选项将会阻止创建默认的 用户/虚拟机/权限 。
消息速率
默认情况下,management plugin 插件显示全局的消息速率,以及每条队列、每个Channel、每个交换机和虚拟主机。这些被称为 basic 消息速率
它还可以显示所有 channel -> exchange , exchange -> queue 和 queue -> channel 组合的消息速率。这些被称为 detailed 消息速率。默认情况下是禁用 detailed 消息速率的,因为当存在大量的 channel 、queue 和 exchange 组合时,它们可能会占用大量的内存。
或者,可以完全禁用消息速率。这可以帮助你从绑定的CPU(CPU-bound)中获得最好的性能。
消息速率的模式可以由 rabbitmq_management 中的配置 rates_mode 来控制。它们可以为 basic (默认值)、detailed 或 none
统计间隔
默认情况下,服务器将每 5000ms 收集一次统计信息。management plugin 中显示的消息速率值会在此期间进行计算。因此,你可能希望增大此值,以便在较长时间内采样本,或者减少具有大量队列或channel服务器上统计时的负载。
为此,请将 rabbit 应用的 collect_statistics_interval 变量的值设置为所需的间隔(单位为毫秒),然后重启 RabbitMQ
HTTP 请求记录
为了生成简单的 HTTP API 请求访问日志,请将 rabbit_management 应用程序中的 http_log_dir 变量的值设置为日志所在的目录,然后重启 RabbitMQ 。注意,只有请求的API为 /api 的才会被记录,而不是组成浏览器的GUI的静态文件的请求。
事件积压
在高负载下,统计事件的处理会增加内存消耗。为了减少这种情况,可以调节 channel 和 queue 统计信息收集器的最大积压数。在 rabbitmq_management 应用的 stats_event_max_backlog 的变量值可设置它们的最大大小。默认为 250
例子
用户切换请求日志记录目录、统计间隔为 10000ms 以及其他显式设置相关参数值为默认值的配置例子如下:
[
{rabbit, [ {tcp_listeners, [5672]},
{collect_statistics_interval, 10000} ] },
{rabbitmq_management, [ {http_log_dir, "/tmp/rabbit-mgmt"},
{rates_mode, basic}] }
].
配置 HTTP 监听器
可以配置 rabbitmq-web-dispatch 来为 management plugin 监听不同的端口或网卡、开启SSL等。为此,你应该配置 listener 配置项,例如更改端口:
[
...
{rabbitmq_management, [{listener, [{port, 12345}]}]},
...
].
或者为 management plugin 开启HTTPS:
[{rabbitmq_management,
[{listener, [{port, 15671},
{ssl, true},
{ssl_opts, [{cacertfile, "/path/to/cacert.pem"},
{certfile, "/path/to/cert.pem"},
{keyfile, "/path/to/key.pem"}]}
]}
]}
].
查看 rabbitmq-web-dispatch 指南来获取更多细节
样本保留策略(sample retention policies)
management plugin 会保留一些数据的样本,例如:消息速率和队列长度。你可以配置这些数据保留多长时间。
[
...
{rabbitmq_management,
[{sample_retention_policies,
%% List of {MaxAgeInSeconds, SampleEveryNSeconds}
[{global, [{605, 5}, {3660, 60}, {29400, 600}, {86400, 1800}]},
{basic, [{605, 5}, {3600, 60}]},
{detailed, [{10, 5}]}]
}]
},
...
].
有三个策略:
- global : 保留概要和虚拟主机页面的数据的时间
- basic : 保留独立连接、channel、交换机和队列数据的时间
- detailed : 保留连接、channel、交换机和队列间配对数据的时间
此配置(默认值)将全局数据以固定5秒(即每5秒采样一次)持续10分钟5秒,然后以固定1分钟持续我小时1分钟采样,然后以固定10分钟持续大约8小时。它保留 basic 数据在固定5秒持续1分5秒,然后固定1分持续1小时; detailed 数据仅持续10秒。 所有三个策略是强制性的,并且必须包含至少一个保留对 {MaxAgeInSeconds, SampleEveryNSeconds} 。
跨域资源共享(CROS)
management plugin 的API默认情况下不允许访问托管在不同来源的网站。要允许的来源网站必须显式地列出在白名单中:
[
...
{rabbitmq_management,
[{cors_allow_origins, ["http://rabbitmq.com", "http://example.org"]}]},
...
].
可以允许任何来源来使用 API 。但是,如果API可以从外部访问的话,则不建议。
[
...
{rabbitmq_management,
[{cors_allow_origins, ["*"]}]},
...
].
CROS 的 pre-flight 请求会被浏览器缓存。 默认情况下, management plugin 插件定义了超时时间为 30 分钟。你可以在配置文件中修改此值。它的单位为秒。
[
...
{rabbitmq_management,
[{cors_allow_origins, ["http://rabbitmq.com", "http://example.org"]},
{cors_max_age, 3600}]},
...
].
集群注意事项
management plugin 插件是会感知集群的。你可以在集群中的一个或多个节点上启用它,并且无论你连接到哪个节点,都可以查看整个集群的信息。
如果要部署一个没有完全开启 management plugin 的集群节点,则仍然需要在每个节点上启用 rabbitmq-management-agent 插件。
当在集群时,management plugin 执行集群范围查询时,这意味着它可能受到各种网络事件(如 分区)的影响。
代理设置
可以通过符合 RFC 1738 的任何代理使 Web UI 可用。以下 Apache 配置示例说明了使用Apache作为代理性的最少必须指令。它假定 management plugin 的 Web UI 在默认端口 15672 。
重启统计数据库
统计数据库是完全存储在内存中的。应该对待它们的所有内容都是短暂的。在 3.6.7 版本之前,统计数据存储在单个节点上。从 3.6.7 开始,每个节点都有自己的统计数据库,其中包含在该节点上记录的统计数据。可以重启这些统计数据库。
在 RabbitMQ 3.6.2 之前,统计数据库是存储在 stats 进程的内存中的,并且在 RabbitMQ 3.6.2 开始,它们是存储在 ETS 表中的。在 3.6.2 之前的版本中,要重启数据库可以使用:
rabbitmqctl eval 'exit(erlang:whereis(rabbit_mgmt_db), please_terminate).'
从 RabbitMQ 3.6.2 到 3.6.5 ,可以使用:
rabbitmqctl eval 'supervisor2:terminate_child(rabbit_mgmt_sup_sup, rabbit_mgmt_sup),rabbit_mgmt_sup_sup:start_child().'
这些命令必须要托管数据库的节点上执行。从 3.6.7 开始,可以使用下面命令来重置每个节点的数据库:
rabbitmqctl eval 'rabbit_mgmt_storage:reset().'
要重置所有节点的数据库:
rabbitmqctl eval 'rabbit_mgmt_storage:reset_all().'
也可以通过 HTTP API 端重置整个数据库:
DELETE /api/reset
重置单个节点:
DELETE /api/reset/:node
内存管理
可以使用 rabbitmqctl 来获取 management database 的内存使用情况:
rabbitmqctl status
或者通过 HTTP API 发送一个 GET 请求到 /api/nodes/name
统计数据是按照上述统计间隔进行的,或者当某些组件被 创建/声明 时(例如,一条新的 connection 或 channel 被打开,或一个队列被声明)或者 关闭/删除时。消息速率不会直接影响 management database 的内存使用。
统计数据库的内存消耗总量取决于事件的触发间隔,有效的速率模式和保留策略。
将 rabbit.collect_statistics_interval 的值增加到 30-60s (注意,该值应以毫秒为单位来设置,例如: 30000) 将减少具有大量 队列/channel/连接 的系统的内存消耗。调整保留策略以保留较少的数据也将有所帮助。
通过使用参数 stats_event_max_backlog 设置最大积压队列大小可以限制 channel 和统计收集器进程的内存使用情况。如果积压队列已满,则新的 channel 和 队列收集将被丢弃,直到前面的队列处理完毕。
统计间隔也可以在运行时更改。这样做对现有的 连接、channel 或 队列没有影响。只会影响新的统计收集实体。
rabbitmqctl eval 'application:set_env(rabbit, collect_statistics_interval, 60000).'
统计数据库也可以被重启(见上面),因此它会强制释放所有内存。
译者题外话
今天在公司里发现中间件 RabbitMQ 队列数据基本没有,但是还是发现它占用了 9GB 多的内存:
一开始,第一感觉认为它是内存泄漏了。所以就顺便翻译了这篇文章,也方便自己日后查看。通地重启统计数据库,即可完全释放掉这部分的内存。