RabbitMQ¶
介绍¶
以下信息主要来自我们在邮件列表中进行的讨论。你可以在这里查看这次讨论
http://lists.openstack.org/pipermail/openstack-discuss/2020-August/thread.html#16362
集群还是非集群?¶
部署 RabbitMQ 时,你有两种可能性
以集群方式部署 rabbit
仅部署一个 rabbit 节点
仅部署一个 rabbit 节点可能被认为是有风险的,主要是因为如果节点宕机,你的服务也会宕机。
另一方面,rabbit 集群有一些缺点,使其配置/管理更加困难。
因此,如果你的集群的可靠性低于单个节点,那么单个节点解决方案更好。
此外,由于许多 OpenStack 服务使用 RabbitMQ 进行内部通信(又名 RPC),因此拥有一个高可用的 rabbit 解决方案是必须的。
如果你选择集群模式,你应该始终在集群中保持奇数个服务器(例如 3 / 5 / 7 等),以避免脑裂问题。
一个 rabbit 来统治它们?¶
你还可以考虑以两种方式部署 rabbit
每个 OpenStack 服务一个 rabbit(集群或非集群)
所有 OpenStack 服务一个大的 rabbit(集群或非集群)
推荐将 rabbit 分割成多个独立的集群,原因如下
降低 rabbit 集群宕机的影响
允许对基础设施的较小部分进行干预
注意:你可以考虑至少将 neutron 和 nova 从其他服务中分离出来,这样你最终将拥有 3 个集群。
注意 2:neutron 是 rabbit 中负载最重的项目。因此请记住,neutron 的 rabbit 集群应该是你最大的。
我应该运行哪个版本的 rabbit?¶
你应该始终尝试运行最新版本的 rabbit。
我们还知道 rabbit 在 3.8 之前可能在集群方面存在一些问题,因此你可能需要运行至少 rabbitmq 3.8.x。
请参阅 https://groups.google.com/forum/#!newtopic/rabbitmq-users/rabbitmq-users/zFhmpHF2aWk
Rabbit 配置推荐¶
我们接下来解释的大部分配置仅适用于集群模式下的 rabbitmq。
服务配置¶
在节点上运行 rabbit 软件时,你可以在以下位置配置一些参数
/etc/rabbitmq/rabbitmq.config # (ubuntu)
最重要的配置如下
Erlang 调度器配置¶
如果你在同一台主机上运行多个 rabbitmq 集群,那么你必须确保所有 rabbitmq/erlang 进程都不会固定到特定的核心。这确保了 erlang 不会争夺使用相同 cpu 核心。为此,使用 -stbt u 或 -sbt u 启动 erlang/beam VM(你可能需要根据启动 erlang 的方式将 - 替换为 +)。
有关详细信息,请参阅 https://erlang.org.cn/doc/man/erl.html#+sbt
net_ticktime 和 heartbeat¶
请参阅 https://rabbitmq.cn/nettick.html 和 https://rabbitmq.cn/heartbeats.html
节点在经过这段时间后被认为已宕机
此配置主要取决于节点之间的网络。
我们认为默认值是好的。
磁盘 / 内存模式¶
https://rabbitmq.cn/clustering.html#cluster-node-types
“在绝大多数情况下,你希望所有节点都是磁盘节点;RAM 节点是一种特殊情况,可用于提高具有高队列、交换或绑定变化的集群的性能。RAM 节点不会提供更高的消息速率。如有疑问,仅使用磁盘节点。”
因此,我们建议保持磁盘节点。
策略¶
RabbitMQ 对队列和交换应用一些策略。请参阅此处:https://rabbitmq.cn/parameters.html
如果你计划部署 RabbitMQ 集群,你将必须添加一个策略。
请记住,Rabbit 只能将一个策略应用于队列或交换。因此,你应该避免在部署中拥有多个策略,或者如果你这样做,请尝试避免重叠的策略,因为你将无法预测哪个策略对队列有效。
pattern¶
策略是根据正则表达式模式应用的。我们达成的模式(来自邮件列表讨论)如下
'^(?!(amq\.)|(.*_fanout_)|(reply_)).*'
这将为所有队列设置 HA,但以下队列除外
以 amq 开头。
包含 _fanout_
以 reply_ 开头。
parameters¶
策略将应用一些参数到队列/交换。
以下是在集群模式下运行 rabbit 时我们推荐的参数(时间以毫秒为单位,如 https://rabbitmq.cn/ttl.html 所述)
"alternate-exchange": "unroutable",
"expires": 3600000,
"ha-mode": "all",
"ha-promote-on-failure": "always",
"ha-promote-on-shutdown": "always",
"ha-sync-mode": "manual",
"message-ttl": 600000,
"queue-master-locator": "client-local"
alternate-exchange¶
请参阅 https://rabbitmq.cn/ae.html
这并非强制性,但是一个很好的功能,可以收集 rabbit 中“丢失”的消息(无法路由的消息)。
expires¶
队列过期时间,以毫秒为单位。默认情况下没有过期时间。
因此,没有消费者的队列将在 1 小时后自动删除。
ha-mode¶
请参阅 https://rabbitmq.cn/ha.html#mirroring-arguments
可以是
all:队列在所有节点上镜像
exactly:还需要 ha-params “count”。将在“count”个节点上复制
nodes:还需要 ha-params “node-names:”。将在“node-names”中的所有节点上复制
我们建议在节点上镜像所有队列,以便在节点上创建的队列也会在其他节点上创建。
ha-promote-on-failure¶
always:(默认)如果主节点意外宕机,将强制将队列主节点移动到另一个节点
when-synced:仅在同步节点上允许移动队列主节点。如果没有同步节点,则需要删除队列
我们保持默认设置,以确保在发生故障时,将选举出一个新的队列主节点并继续工作。
ha-promote-on-shutdown¶
always:如果主节点关闭,将强制将队列主节点移动到另一个节点
when-synced:(默认)
我们更喜欢在所有情况下(即,我们选择队列的可用性而不是避免由于不同步镜像的提升而导致的消息丢失)将队列主节点移动到未同步的镜像。
ha-sync-mode¶
请参阅 https://rabbitmq.cn/ha.html#replication-factor
automatic:可以是阻塞的,将始终复制队列,但可能会在执行此操作时阻塞 io
manual:(默认)模式。新的队列镜像只会接收新消息(队列中已有的消息不会被镜像)。
对于我们来说,使用手动模式没有问题,因为大多数时候 OpenStack 队列都是空的。
message-ttl¶
队列中的消息 TTL。
默认情况下,没有 TTL。
我们建议将其设置为 600000(10 分钟)。
这应该很安全,因为大多数 OpenStack 元素在 300 秒后超时。
因此,10 分钟内未消费的消息将从队列中删除。
master-locator¶
确定在创建队列时哪个节点被选为 master。
client-local:(默认)选择客户端连接的队列所在的节点
min-masters:选择托管绑定 master 数量最少的节点
random
我们建议保持 client-local(默认值)。
在 OpenStack 服务上¶
rabbit_ha_queues¶
你可能会在一些配置文件中看到这个参数。
但现在这没用了,因为策略正在设置它。
amqp_durable_queues¶
请参阅此处:https://rabbitmq.cn/queues.html#durability
“在大多数其他情况下,持久队列是推荐的选择。对于复制队列,唯一的合理选择是使用持久队列。”
因此,由于我们在策略中启用了 HA,因此我们必须启用持久队列
因此,设置
amqp_durable_queues = True
在每个 OpenStack 配置文件中
请注意,队列(或交换)的持久性无法在队列创建后设置。因此,如果你忘记在开始时设置它,你将必须在 OpenStack 重新创建具有正确持久性的队列之前删除你的队列。
rabbit_transient_queues_ttl¶
瞬态队列的默认 TTL 为 30 分钟,但对于 neutron(服务器和代理),这太长了。
例如,在重新启动代理时,它将在 rabbit 集群中保留瞬态队列 30 分钟。大多数这些队列都是 fanout 队列,因此它们会堆积消息。
在大型集群上,你很快就会最终得到数百万条消息(在 30 分钟内)。
因此,建议大幅降低此值,以便更快地删除瞬态队列(例如 60 秒)
rabbit_transient_queues_ttl = 60
update_resources_interval¶
这是一个 nova 设置:https://docs.openstack.org/nova/2025.2/configuration/config.html#DEFAULT.update_resources_interval
此选项指定 update_available_resource 定期任务应该运行的频率。
默认的周期间隔为 60 秒,对于大规模来说可能太频繁了。
建议将此值增加到适合你需求的数值,例如 600 秒
update_resources_interval = 600