阅读 213

RabbitMQ系列(七)RabbitMQ的参数与策略

概述

尽管RabbitMQ的许多配置存放于配置文件中,但有些配置不适合在配置文件中:
1)如果它们需要在集群中的所有节点上都是相同的;
2)如果它们可能在运行时更改;
RabbitMQ称这些为参数。参数可以通过调用rabbitmqctl工具或者HTTP API进行设置。

全局与虚拟主机参数

1、虚拟主机参数
虚拟主机参数绑定到虚拟主机,由组件名称、名称和值组成。
示例:Federation upstrea。它的目标是一个组件(federation-upstream),它的名称绑定到一个虚拟主机并且它的值定义了连接到上游代理的参数。

可以设置、清除和列出虚拟主机范围的参数:
rabbitmqctl工具:

rabbitmqctl set_parameter [-p vhost] <component_name> <name> <value>
rabbitmqctl clear_parameter [-p vhost] <component_name> <name>
rabbitmqctl list_parameters [-p vhost]
复制代码

HTTP API

PUT /api/parameters/{component_name}/{vhost}/{name}
DELETE /api/parameters/{component_name}/{vhost}/{name}
GET /api/parameters
复制代码

2、全局参数
全局参数没有绑定到特定虚拟主机,由名称和值组成。
示例:集群的名称。

可以设置、清除和列出全局参数:
rabbitmqctl工具

rabbitmqctl set_global_parameter <name> <value>
rabbitmqctl clear_global_parameter <name>
rabbitmqctl list_global_parameters
复制代码

HTTP API

PUT /api/global-parameters/name
DELETE /api/global-parameters/name
GET /api/global-parameters
复制代码

由于参数值是JSON文档,所以在使用rabbitmqctl在命令行创建参数值时,通常需要引用它。在Unix上,通常最容易用单引号('')引用整个文档,并在其中使用双引号("")。在Windows上,你必须转义每个双引号("")。出于这个原因,我们给出了Unix和Windows的示例。
参数驻留在RabbitMQ用于定义虚拟主机、交换器、队列、绑定、用户和权限的数据库中。参数与其他对象定义一起由管理插件的导出功能导出。
Federation和Shovel插件使用虚拟主机范围的参数。MQTT插件使用全局参数。

策略

策略为什么存在?

策略是虚拟主机范围的。
在我们解释什么是策略以及如何使用它们之前,解释一下为什么将它们引入RabbitMQ是有帮助的。
除了强制属性(如durable或者exclusive属性),RabbitMQ中的队列和交换机还有可选参数(参数),有时也称为x-arguments。当客户端声明队列(交换机)并控制各种可选特性(如队列长度限制或TTL)时,就会提供这些特性。 RabbitMQ支持的某些协议中客户端控制属性通常工作得很好,但它们不灵活:更新TTL值或者镜像参数时需要应用程序变更、重新部署和队列重新声明(其中包括删除)。此外,无法控制队列和交换机分组的额外参数。策略用于解决这些问题。
一个策略通过名称(使用正则表达式)匹配一个或多个队列,并将其(策略)定义(可选参数的映射)附加到匹配队列的x-arguments上。换句话说,可以使用一个策略一次性配置多个队列的x参数,并通过更新策略定义一次性更新它们。
在RabbitMQ的现代版本中,可以由策略控制的特性集与可以由客户端提供的参数控制的特性集是不同的。

策略如何工作?

关键的策略属性:
1)name:它可以是任何名称,但建议使用基于ASCII的、不带空格的名称;
2)pattern:匹配一个或多个队列(交换机)名称的正则表达式。可以使用任何正则表达式;
3)definition:Key/Value的集合(比如JSON文档),将被注入到匹配队列和交换机的可选参数中;
4)priority:见下面;

策略自动匹配交换机和队列,并且帮助确定它们的行为。每个交换器或队列最多有一个策略匹配(请参阅下面的组合策略定义),然后每个策略向匹配队列(交换器)注入一组键-值对(策略定义)。
策略可以只匹配队列,只匹配交换机或者两者。这可以在创建策略时使用“apply-to”标识进行控制。
策略可以随时变更。当一个策略定义被更新,它将重新运用到匹配的交换机和队列。通常它会在瞬间发生,但对于非常繁忙的队列可能会花费一些时间(比如几秒钟)。策略是在每次创建交换或队列时匹配和应用的,而不仅仅是在创建策略时。
策略可用于配置Federation插件、镜像队列、备用交换机、死信、每个队列TTL和队列长度最大值。

定义策略如下:
rabbitmqctl工具

rabbitmqctl set_policy federate-me \
    "^amq\." '{"federation-upstream-set":"all"}' \
    --priority 1 \
    --apply-to exchanges
复制代码

rabbitmqctl (Windows)

rabbitmqctl.bat set_policy federate-me ^
    "^amq\." "{""federation-upstream-set"":""all""}" ^
    --priority 1 ^
    --apply-to exchanges
复制代码

HTTP API

PUT /api/policies/%2f/federate-me
    {"pattern": "^amq\.",
     "definition": {"federation-upstream-set":"all"},
     "priority": 1,
    "apply-to": "exchanges"}
复制代码

Web UI

导航至:Admin > Policies > Add/update 进行新增/更新策略;
输入名称:"federate-me",模式:"^amq\.",选择应用到:"Exchanges";
输入:"federation-upstream-set" = "all"在第一行;
点击“新增策略”
复制代码

这将匹配在虚拟主机“/”中,所有以“amq.”开头的名称、Key为“federation-upstream-set”,值为“all”的交换机。“pattern”参数是一个正则表达式,用于匹配交换机或者队列名称。
如果有多个策略可以匹配给定的交换或队列,则使用具有最大优先级的策略。 “apply-to”可以是 "exchanges"、"queues" 或者 "all"。“apply-to”和“priority”设置是可选的,在这种情况下,默认值分别是“all”和“0”。

Federation策略定义

在某些情况下,我们可能希望对资源运用多个策略定义。例如,我们可能需要联合和镜像一个队列。在任何给定的时间内,最多只能将一个策略应用于一个资源,但是我们可以在该策略中应用多个定义。
Federation策略定义将需要指定upstream集,所以在定义中我们需要federation-upstream-set的Key。另一方面,为了将一些队列定义为镜像的,我们还需要为策略定义ha-mode的Key。策略定义只是一个JSON对象,可以在同一个策略定义中组合多个键。

示例:
rabbitmqctl工具

rabbitmqctl set_policy ha-fed \
    "^hf\." '{"federation-upstream-set":"all", "ha-mode":"exactly", "ha-params":2}' \
    --priority 1 \
    --apply-to queues
复制代码

rabbitmqctl (Windows)

rabbitmqctl set_policy ha-fed ^
    "^hf\." '{"federation-upstream-set:"all", "ha-mode":exactly", "ha-params":2}' ^
    --priority 1 ^
    --apply-to queues
复制代码

HTTP API

PUT /api/policies/%2f/ha-fed
    {"pattern": "^hf\.",
    "definition": '{"federation-upstream-set":"all", "ha-mode":"exactly", "ha-params":2}',
    "priority": 1,
    "apply-to": "queues"}
复制代码

Web UI

导航至:Admin > Policies > Add/update 进行新增/更新策略;
输入名称:"ha-fed",模式:"^hf\.",选择应用到:"Queues";
输入:"federation-upstream-set" = "all"在第一行;
在下面的表格行输入: "ha-mode" = "exactly""ha-params" = 2
点击“新增策略”
复制代码

这将匹配所有以"^hf."开头的队列,应用"federation-upstream-set"以及策略定义。

Operator策略

与常规策略的不同

有时执行某些策略对于操作者来说是必要的。例如,可能希望强制队列TTL,但仍然让其他用户管理策略。Operator策略可以实现。
Operator策略与常规策略非常相似,但是它们的定义使用不同。在将结果应用到匹配队列之前,它们与常规策略定义合并。

因为Operator策略可以特例地修改队列属性,进而更改应用程序假设和语义。Operator策略仅针对如下几个参数限制:
1)expires
2)message-ttl
3)max-length
4)max-length-bytes
上面的参数都是数值型的。原因在下一节中解释。

解决与常规策略的冲突

Operator策略和常规策略可以在它们的定义中包含相同的Key。如果出现这种情况,选择较小的值作为有效值。例如:如果Operator策略设置max-length的值为50,常规策略设置max-length的值为100,将使用50。然而,如果常规策略设置为20,那么将使用20。因此,Operator策略不是覆盖常规策略的值。它们执行限制,但尽可能不覆盖用户提供的策略。

Operator策略定义

Operator策略定义方式与常规(用户)策略相似。当使用rabbitmqctl工具时,命令名称为set_operator_policy而不是set_policy;在HTTP API中,请求路径/api/policies/变为/api/operator-policies/。

rabbitmqctl工具

rabbitmqctl set_operator_policy transient-queue-ttl \
    "^amq\." '{"expires":1800000}' \
    --priority 1 \
    --apply-to queues
复制代码

rabbitmqctl (Windows)

rabbitmqctl.bat set_operator_policy transient-queue-ttl ^
    "^amq\." "{""expires"": 1800000}" ^
    --priority 1 ^
    --apply-to queues
复制代码

HTTP API

PUT /api/operator-policies/%2f/transient-queue-ttl
                {"pattern": "^amq\.",
                 "definition": {"expires": 1800000},
                 "priority": 1,
                 "apply-to": "queues"}
复制代码

Web UI

导航至:Admin > Policies > Add/update 进行新增/更新策略;
输入名称:"transient-queue-ttl",模式:"^amq\.",选择应用到:"Queues";
输入:""expires" = 1800000"在第一行;
点击“新增策略”
复制代码

上一篇:RabbitMQ系列(六)RabbitMQ的配置
下一篇:RabbitMQ系列(八)RabbitMQ的日志