跳至主内容

RabbitMQ 3.0 搞砸了一些东西

·6 分钟阅读
Simon MacMullen

RabbitMQ 包含许多很棒的新功能。但为了实现其中的一些功能,我们需要改变一些东西。所以在这篇博文中,我将列出其中一些内容,以防您需要对它们进行任何操作。

镜像队列策略

有什么变化? 在 RabbitMQ 3.0 中,声明队列时不再通过 x-ha-policy 参数来控制队列镜像。虽然您的应用程序可以继续声明此参数,但它不会再使队列被镜像。取而代之的是,您可以声明一个或多个策略(policies),由这些策略来控制哪些队列需要镜像以及如何进行镜像。

为什么要改? 任何使用过镜像队列的人都会告诉您,要求应用程序知晓哪些队列已镜像是一件令人头疼的事。新方法将配置置于代理(broker)端,这才是它应有的位置,同时也支持随时更改镜像策略。

我该怎么做? 您需要确保您的队列仍然处于镜像状态。有关完整文档,请参阅此处;但如果您只是想确保所有队列(除自动生成名称的队列外)都在所有节点上进行镜像,请运行

rabbitmqctl set_policy HA '^(?!amq\\.).*' '{"ha-mode": "all"}'

新联邦(Federation)

有什么变化? RabbitMQ 3.0 中联邦的配置方式完全不同。x-federation 交换机类型不再存在;取而代之的是,通过策略(policy)将普通交换机设置为联邦交换机,方式与 HA 队列相同。此外,上游(upstreams)也是动态定义的。

为什么要改? 同样,您的应用程序无需了解联邦。在 rabbitmq.config 中配置联邦不仅复杂,还让许多人感到困惑。而且,为了添加新的上游而不得不重启代理的做法体验并不好。

但我现有的联邦设置是正常的!你们把它搞坏了。 迁移到新的联邦实现方式需要做一些工作。在此期间,您可以使用 rabbitmq_old_federation 插件。这是 RabbitMQ 3.0 对 2.8.7 版本联邦插件的回溯移植。要使用它,请

rabbitmq-plugins disable rabbitmq_federation

rabbitmq-plugins enable rabbitmq_old_federation

然后编辑您的 rabbitmq.config 文件,将 rabbitmq_federation 部分重命名为 rabbitmq_old_federation

新集群(Clustering)

有什么变化? rabbitmqctl 中的集群设置命令已更改。

为什么要改? 旧的命令不太便于用户使用。

我需要做什么? 如果您已有现成的集群,则无需做任何操作。如果您是通过脚本来创建集群,则需要进行编辑。特别是,rabbitmqctl cluster 应替换为 rabbitmqctl join_cluster,但

  • 您不需要先调用 rabbitmqctl reset
  • 您不需要在命令行中列出所有节点;如果您提供了多个节点,它们将被视为尝试建立集群的节点列表
  • 新节点是作为磁盘(disc)节点还是内存(RAM)节点,由 --disc--ram 标志决定。默认情况下为磁盘节点。

有关更多详细信息,请参阅文档

移除 "immediate" 标志

有什么变化? 我们移除了对 AMQP basic.publish 中极少使用的 "immediate" 标志的支持。

为什么要这么做? 对 "immediate" 的支持增加了代码库许多部分的复杂性,尤其是在涉及镜像队列时。它也阻碍了我们对镜像队列进行重大性能提升。

我该怎么做? 如果您只是希望发布消息并在无法立即被消费时将其丢弃,您可以发布到 TTL 为 0 的队列中。

如果您还需要发布者能够确定消息已被丢弃,您也可以使用 DLX(死信交换机)功能,将此类消息路由到另一个队列,发布者可以从该队列中消费它们。

frame_max

有什么变化? 如果客户端发送的帧大于为该连接协商出的 frame_max 设置,RabbitMQ 服务器现在会断开该客户端的连接。

为什么要改? 恶意(或编写不当的)客户端可能会发送任意大的帧,导致服务器内存耗尽。

我为什么要关心? 不幸的是,有些客户端没有正确实现 AMQP 分帧。RabbitMQ 3.0 会允许客户端超过 frame_max 几个字节(以允许“差一错误”或错误地排除了帧头的情况),但如果您的客户端分帧逻辑有缺陷,在尝试发送大于 frame_max(默认值为 128kb;查看文档以了解如何增加此值)的消息后,您将被断开连接。

管理和 JSON-RPC 通道端口变更

有什么变化? 管理插件现在监听 15672 端口,而不是 55672。JSON-RPC 通道现在监听 15670 端口,而不是 55670。

为什么要改? 在许多操作系统中,旧端口属于临时端口范围,这意味着网页浏览器和其他客户端应用程序可能会随意使用这些端口。您不应该在这些端口上监听。

特别要注意,我们发现管理插件的 Web UI 在指向 localhost 上已停止的代理时,可能会导致浏览器连接到 55672 端口上的自身。这会阻止代理重新启动。

我该怎么做? 希望您无需任何操作。RabbitMQ 会尝试打开旧端口并发送 HTTP 重定向到新端口。但如果您使用的是除了浏览器以外的应用程序来访问 HTTP API,它可能不支持 HTTP 重定向。如果是这样,您需要将其指向新端口。

注意,3.0 版本之前的 rabbitmqadmin 正是属于此类应用程序。抱歉。

另请注意,STOMP 插件仍然监听 61313 端口。尽管这也在临时端口范围内,但它已是 STOMP 最接近的标准端口,因此我们必须保留它。

过期(expiration)属性

有什么变化? 我们现在要求消息属性中的 expiration 字段如果被设置,则必须能够解析为整数。

为什么要改? 为了支持每条消息的 TTL(存活时间),我们需要一个获取消息 TTL 的位置,这显然就是该字段。不幸的是,AMQP 标准将其定义为字符串,因此我们尝试将其解析为整数,如果解析失败,将抛出通道异常。

我该怎么做? 确保如果您正在使用该属性,是因为您希望 RabbitMQ 使该消息过期,并确保将其设置为可以解析为整数的字符串。

© . This site is unofficial and not affiliated with VMware.