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
除了对人和机器更友好之外,此新的配置文件还包含对密钥和某些值类型(例如文件路径)的验证。如果证书或公钥文件不存在,节点将报告该错误并无法启动。未知或拼写错误的键也是如此。
将来会有一篇关于新格式的更详细的文章。
对等发现子系统
当 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.x 版本,从 3.6.7 开始。
重新设计的 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 发行版 包含所有发行说明并提供备份包下载选项
如果您目前从 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 并让我们知道在 邮件列表 上的情况。为了简化过渡,提供了一个新的 升级文档指南。当然,请先查阅 完整更改日志!