RabbitMQ 3.7 新特性
经过一年多的努力,RabbitMQ 3.7.0 已在假期开始前悄然发布。此次发布深受社区对 3.6.x 版本反馈的启发。在本篇文章中,我们将介绍此次发布的一些亮点。
RabbitMQ 3.7.0 专注于提升自动化友好性和可操作性。
新的配置格式
首先从新的配置格式说起。过去,RabbitMQ 一直使用 Erlang 术语文件进行配置。我们将在另一篇博客中讨论这种格式的优缺点。最重要的一点是,传统格式难以生成,这使得自动化变得复杂。
新格式深受 sysctl 和 ini 文件的启发。它对人类更易读,且对于配置管理工具来说更容易生成。
对比一下我们的 TLS 指南中的以下示例。
经典(Erlang 术语)格式
[
{ssl, [{versions, ['tlsv1.2', 'tlsv1.1']}]},
{rabbit, [
{ssl_listeners, [5671]},
{ssl_options, [{cacertfile,"/path/to/ca_certificate.pem"},
{certfile, "/path/to/server_certificate.pem"},
{keyfile, "/path/to/server_key.pem"},
{versions, ['tlsv1.2', 'tlsv1.1']}
]}
]}
].
与新格式对比
listeners.ssl.1 = 5671
ssl_options.cacertfile = /path/to/ca_certificate.pem
ssl_options.certfile = /path/to/server_certificate.pem
ssl_options.keyfile = /path/to/server_key.pem
ssl_options.versions.1 = tlsv1.2
ssl_options.versions.2 = tlsv1.1
除了对人和机器更友好之外,这个新的配置文件还包含了对键(key)以及文件路径等特定值类型的验证。如果证书或公钥文件不存在,节点会发出报告并启动失败。对于未知或拼写错误的键也是如此。
敬请期待未来关于新格式的更详细的博文。
对等节点发现子系统
当 RabbitMQ 集群首次形成时,新启动的节点需要有一种方式来发现彼此。在 3.6.x 及之前的版本中,有两种方法可以实现:
- CLI 工具
- 在配置文件中列出节点列表
前一种选项被一些配置工具使用,但通常对自动化不太友好。后者更方便,但有其局限性:节点集是固定的,更改它需要重新部署配置文件并重启节点。
还有第三种选择,它在社区中已经存在几年了:由 Gavin Roy 开发的 rabbitmq-autocluster。该插件修改了 RabbitMQ 的启动过程,使对等节点发现更加动态:例如,可以从 AWS 自动扩缩容组或像 etcd 这样的外部工具中获取节点列表。
在 RabbitMQ 3.7.0 中,我们采纳了 rabbitmq-autocluster 的核心思想,并结合我们对 RabbitMQ 生产环境安装的经验以及社区反馈进行了改进,将其集成到了核心组件中。
其结果是一个新的对等节点发现子系统,我们将在另一篇博客中详细介绍。它支持多种机制和平台:
- AWS(EC2 实例标签或自动扩缩容组)
- Kubernetes
- etcd
- Consul
- 预配置的 DNS 记录
- 配置文件
并且方便未来引入对更多选项的支持。
分布式管理插件
统计数据库过载是早期版本中的一个主要痛点。这与最初的管理插件设计有关,该设计将整个集群的统计数据收集和聚合委托给单个专用节点。无论该节点效率多高,这都存在可扩展性限制。
在某种程度上,这个问题占据了大量支持工单和邮件列表讨论的内容,因此我们决定对管理插件进行重大且破坏性的重新设计。
在新的设计中,每个节点负责托管和聚合其自身的统计信息,并在收到 HTTP API 请求时根据需要从其他节点请求数据。我们现在拥有近一年的支持数据和用户反馈,并很高兴地报告,统计数据库过载已不再是一个问题。
这些更改已向后移植到从 3.6.7 开始的 3.6.x 版本中。
重新设计的 CLI 工具
RabbitMQ CLI 长期存在的一个局限是插件无法对其进行扩展。这种情况从 3.7.0 版本开始改变。像 Shovel 和 Federation 这样的插件现在可以提供自己的命令,帮助操作员评估系统状态并对其进行管理。
rabbitmq-diagnostics 是为操作员提供的新命令,其中包含了一些以前在 rabbitmqctl 中可用的命令,但也引入了新的命令。诊断命令列表将根据我们在邮件列表上的用户反馈持续增长。
代理协议支持
客户端通过 HAproxy 或 AWS ELB 等代理连接到 RabbitMQ 节点是非常普遍的。这给操作员带来了麻烦:节点无法获取真实的客户端 IP 地址,因此无法记录、在管理 UI 中显示等。
幸运的是,针对这个问题已有一个解决方案,并得到了主流代理工具的支持:Proxy 协议。从 3.7.0 开始,如果操作员选择启用,RabbitMQ 将支持 Proxy 协议。它需要兼容的代理,但不需要修改客户端库。根据 Proxy 协议规范的要求,当协议启用时,不再支持直接的客户端连接。
跨协议 Shovel
Shovel 插件现在支持双向(作为源和目标)的 AMQP 1.0 端点。这意味着 Shovel 现在可以将消息从仅支持 AMQP 1.0 的消息代理移动到 RabbitMQ,反之亦然。
运营商策略
操作员策略的作用与常规策略类似,但只能由管理员管理,并且会覆盖用户定义的策略。将 RabbitMQ 作为服务提供的运营商可以使用它们来限制特定计划上的最大队列长度。
基于虚拟主机的消息存储
从 3.7.0 开始,每个虚拟主机(vhost)都有其自己的消息存储(实际上是两个存储)。这样做主要是为了提高弹性,将潜在的消息存储故障限制在单个 vhost 内,但在使用多个虚拟主机的环境中,它也可以提高磁盘 I/O 利用率。
其他值得注意的变化
最低要求的 Erlang/OTP 版本现在为 19.3。我们强烈建议至少使用 19.3.6.5。该版本包含两个错误的修复,这些错误可能导致带有活动 TCP 连接的节点无法关闭,从而可能极大地增加自动升级的复杂性。该版本连同 20.1.7 和 20.2.x 版本,包含了针对最近披露的 ROBOT TLS 攻击的修复。
在 3.7 的开发周期中,我们为客户端引入了新的版本编号方案。Java 和 .NET 的客户端库版本不再与 RabbitMQ 服务器版本绑定。这使得客户端能够更快速地迭代,并遵循对其本身更有意义的版本方案。Java 和 .NET 客户端目前都已进入 5.x 版本,并包含了需要提升主版本号的重要更改,例如对 lambda 和 .NET Core 的支持。
软件包分发变更
从 3.7.0 开始,RabbitMQ 软件包(二进制文件)通过以下三个服务进行分发:
- Bintray 提供软件包下载以及 Debian 和 Yum (RPM) 存储库
- Package Cloud 提供 Debian 和 Yum 存储库
- GitHub releases 包含所有发行说明并提供备用软件包下载选项
如果您目前从 rabbitmq.com 获取软件包,请切换到上述选项之一。
与 rabbitmq.com 传统的 apt 存储库不同,Package Cloud 和 Bintray 提供旧版本的软件包。当然,现在 RabbitMQ 本身以及我们的零依赖 Erlang/OTP RPM 软件包都有官方的 Yum 存储库。
Java 客户端版本现在仅通过 Maven 存储库(主要是 Maven Central)分发。.NET 客户端版本仅通过 NuGet 提供。
升级到 3.7.x
我们鼓励所有用户升级到 3.7.x,并在邮件列表上告诉我们您的使用感受。为了简化过渡,我们提供了一份新的升级文档指南。当然,请务必先查阅完整的变更日志!
