RabbitMQ 3.7 的新功能
经过一年多的努力,RabbitMQ 3.7.0 在假期季开始前悄然发布。此版本的发布深受社区对 3.6.x 反馈的启发。在这篇文章中,我们想介绍此版本中的一些亮点。
RabbitMQ 3.7.0 专注于自动化友好性和可操作性。
新的配置格式
让我们从新的配置格式开始。历史上,RabbitMQ 一直使用 Erlang term 文件进行配置。我们将在另一篇博文中介绍其优点和缺点。最重要的是,经典格式难以生成,这使自动化变得复杂。
新格式深受 sysctl 和 ini 文件的启发。它对人类更易读,并且更易于为配置工具生成。
比较我们 TLS 指南中的以下示例。
经典(Erlang term)格式
[
{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
除了对人类和机器更友好之外,这个新的配置文件还包括对键和某些值类型(如文件路径)的验证。如果证书或公钥文件不存在,节点将报告并启动失败。未知或拼写错误的键也是如此。
期待未来有关新格式的更详细的文章。
对等节点发现子系统
当 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 中显示等等。
幸运的是,这个问题有一个解决方案,并且受到一些最流行的代理工具的支持:代理协议。从 3.7.0 开始,如果操作员选择加入,RabbitMQ 支持代理协议。它需要兼容的代理,但不需要客户端库更改。根据代理协议规范要求,启用协议后,不再支持直接客户端连接。
跨协议 Shovel
Shovel 插件 现在在两个方向(作为源和目标)都支持 AMQP 1.0 端点。这意味着 Shovel 现在可以将消息从仅 AMQP 1.0 的代理移动到 RabbitMQ 或反之亦然。
操作员策略
操作员策略 的工作方式与 常规策略 非常相似,但只能由管理员管理,并将覆盖用户定义的策略。提供 RabbitMQ 作为服务的操作员可以使用它们来限制例如特定计划的 最大队列长度。
每个虚拟主机消息存储
从 3.7.0 开始,每个虚拟主机都有自己的消息存储(实际上是两个存储)。这样做主要是为了提高弹性,并将潜在的消息存储故障限制在单个虚拟主机,但它也可以改善使用多个虚拟主机的环境中的磁盘 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,并在 邮件列表 上告知我们进展情况。为了简化过渡,有一个新的 升级文档指南。当然,请首先查阅 完整变更日志!