云计算百科
云计算领域专业知识百科平台

RabbitMQ 3.9.8 维护版本发布详解:核心服务器缺陷修复与插件增强全解析

  • 后端
  • 消息队列
  • 消息路由

【免费下载链接】rabbitmq-server

Open source RabbitMQ: core server and tier 1 (built-in) plugins

项目地址:
https://gitcode.com/gh_mirrors/ra/rabbitmq-server

点击查看 免费下载

导读

RabbitMQ 3.9.8 是 3.9.x 系列的一个维护版本(maintenance release),聚焦于修复核心服务器中几个影响生产稳定性的缺陷(mandatory 发布导致的内存增长、内存诊断命令读取失败、Stream 副本 IP 通告问题),同时对 Prometheus、Management、AWS Peer Discovery 与 Web STOMP 四个插件进行了增强。本文以官方发布说明为主线,结合本仓库源码逐项剖析每个变更的实现细节,帮助运维与开发者在升级到 3.9.8 前后理解这些修复的原理、排查对应问题,并掌握相关命令与配置的实战用法。


版本概览:升级路径与 Erlang 兼容性

3.9.8 是一个维护版本,不引入破坏性 API 变更。升级前需注意两点:

  • 从低于 3.9.0 的版本升级:请先参阅 v3.9.0 发布说明 中的 Upgrading to 3.9 章节,该章节涵盖了跨小版本升级所需的前置条件(如功能开关、数据迁移等)。
  • Erlang 版本要求:本版本要求至少 Erlang 23.2,发布时支持最新的 Erlang 24 版本 24.1.2。Erlang 版本与 RabbitMQ 的完整兼容矩阵请参阅官方 RabbitMQ 与 Erlang/OTP 兼容性矩阵文档,其要求会随 Erlang 版本演进而变化,务必以官方最新矩阵为准。

发布说明的历史记录统一存放在本仓库的 release-notes 目录下,社区鼓励贡献者在提交变更时同步更新对应的发布说明文件,这有助于发布流程自动化和发布节奏的一致性。


核心服务器(Core Server)缺陷修复

修复一:mandatory 发布到经典队列时 channel 内存无限增长

问题现象:当使用 mandatory 标志发布消息到经典队列(classic queues),且未开启 publisher confirms 时,channel 的内存使用量会无限制增长。对应的 GitHub issue 编号为 #3560。

问题成因:从源码结构看,经典队列的投递路径由 rabbit_classic_queue.erl 中的 deliver/3 函数实现:

deliver(Qs0, Msg0, Options) ->
%% add guid to content here instead of in rabbit_basic:message/3,
%% as classic queues are the only ones that need it
Msg = mc:prepare(store, mc:set_annotation(id, rabbit_guid:gen(), Msg0)),
Mandatory = maps:get(mandatory, Options, false),
MsgSeqNo = maps:get(correlation, Options, undefined),
Flow = maps:get(flow, Options, noflow),
Confirm = MsgSeqNo /= undefined,
…

关键点在于:Confirm = MsgSeqNo /= undefined,即确认机制是否生效取决于投递选项中是否存在 correlation(消息序列号)。当启用 publisher confirms 时,channel 会通过消息序列号跟踪未确认消息并最终清理;而当仅使用 mandatory 而未开启 confirms 时,mandatory 消息在路由失败后的回退处理(由 rabbit_channel.erl 中的 process_routing_mandatory/5 承担)与未确认消息的记账逻辑之间缺少了正确的清理路径,导致 channel 进程中与 mandatory 发布相关的内部状态不断累积。

修复效果:3.9.8 修复了该记账/清理路径,使 mandatory 消息在路由结果确定后能够及时释放相关内存状态,channel 的内存占用恢复稳定。

实战建议:如果你的生产环境大量使用 mandatory 标志进行消息路由可达性校验,建议:

  • 升级到 3.9.8 及以上版本;
  • 优先配合使用 publisher confirms,将 mandatory 与 confirms 结合,通过 basic.return 回调处理不可路由消息,而非单纯依赖 mandatory 标志;
  • 升级后用 rabbitmq-diagnostics memory_breakdown 观察 connection_channels 类别内存是否长期保持平稳。
  • 修复二:rabbitmq-diagnostics memory_breakdown 无法读取连接相关进程内存

    问题现象:rabbitmq-diagnostics memory_breakdown 命令在读取 connection reader、connection writer 以及 channel 进程的内存时失败。对应 GitHub issue 编号为 #3570。

    命令背景:memory_breakdown 是 RabbitMQ 内存排查的核心诊断命令之一。根据 rabbitmq-diagnostics.8 手册页,其完整语法为:

    rabbitmq-diagnostics memory_breakdown [–unit <memory_unit>]

    支持的内存单位包括:bytes、megabytes、gigabytes、terabytes,典型用法示例:

    # 以 GB 为单位显示节点各分类内存占用
    rabbitmq-diagnostics memory_breakdown –unit gigabytes

    该命令会按类别(连接 reader/writer、channel 进程、队列进程、ETS 表、二进制堆等)展示节点内存分布,是定位内存泄漏与内存水位过高问题时的首选工具,更深入的内存管理背景可参考官方 RabbitMQ 内存使用指南。

    问题成因与修复:修复前,命令在遍历连接 reader、writer 与 channel 进程并查询其内存大小时存在读取失败路径;3.9.8 修正了该内存读取逻辑,使上述三类进程的内存数据可以被正常聚合展示。升级后执行 memory_breakdown 应能完整输出所有进程类别的内存明细。

    修复三:Stream 副本通告不可达 IP 地址(NAT/Docker 场景)

    问题现象:在某些环境(例如 Docker 部署中位于 NAT 之后的节点)下,Stream 副本向集群对等节点通告的 IP 地址无法被对端访问,导致副本间通信失败。对应上游问题编号为 rabbitmq/osiris#53。

    修复方案:除了通告 IP 地址外,节点现在同时通告 RabbitMQ 节点主机名,使其他对等节点可以通过主机名解析到外部可见的 IP 地址。

    从 rabbit_stream.erl 的源码可以看到 Stream 插件如何决定对外通告的地址:

    advertised_endpoint(Transport) ->
    {advertised_host(Transport), advertised_port(Transport)}.

    advertised_host(tcp) -> host();
    advertised_host(ssl) -> tls_host().

    host() ->
    case application:get_env(rabbitmq_stream, ?K_AD_HOST, undefined)
    of
    undefined ->
    hostname_from_node();
    Host ->
    rabbit_data_coercion:to_binary(Host)
    end.

    hostname_from_node() ->
    case re:split(
    rabbit_data_coercion:to_binary(node()), "@",
    [{return, binary}, {parts, 2}])
    of
    [_, Hostname] ->
    Hostname;
    [_] ->
    {ok, H} = inet:gethostname(),
    rabbit_data_coercion:to_binary(H)
    end.

    即:如果未显式配置 stream.advertised_host,插件默认从节点名(node@hostname)中提取主机名部分作为通告地址。3.9.8 之后,Stream 副本在与集群对等节点交互时会同时携带并通告节点主机名,方便对端解析出可达地址。

    实战建议:在 NAT/Docker 等网络拓扑复杂的部署中,建议显式配置 Stream 插件地址相关参数(对应配置项位于 rabbitmq_stream.schema,即 stream.advertised_host 等),以确保对外通告的是稳定、可达的地址:

    # rabbitmq.conf
    stream.advertised_host = <外部可达主机名或IP>
    stream.advertised_port = <外部可达端口>


    Prometheus 插件增强:/metrics/detailed 端点暴露更多数据

    3.9.8 增强了 Prometheus 插件,GET /metrics/detailed 端点现在暴露更多指标数据。对应 PR 编号为 #3520。

    在源码层面,prometheus_rabbitmq_core_metrics_collector.erl 定义了详细指标的命名规则——所有 /metrics/detailed 专属指标使用 rabbitmq_detailed_ 前缀:

    %% Used by `/metrics/detailed` endpoint
    -define(DETAILED_METRIC_NAME_PREFIX, <<"rabbitmq_detailed_">>).

    collect_mf('detailed', Callback)(见 该文件第 292 行起)负责按详细模式收集指标,并额外引入三类仅在 detailed 端点可用的指标组(定义于 第 232-273 行):

    指标组说明示例指标
    METRICS_CLUSTER 集群级指标 vhost_status(vhost 是否运行)、exchange_bindings(exchange 绑定数)、exchange_name(exchange 枚举)
    METRICS_MEMORY_BREAKDOWN 逐类别内存明细 memory_client_connection_reader_bytes、memory_client_connection_channel_bytes、memory_classic_queue_erlang_process_bytes、memory_quorum_queue_erlang_process_bytes、memory_stream_erlang_process_bytes 等
    METRICS_RAW(detailed 模式) 按 vhost/队列细分的原始指标 含 auth_attempt_detailed_total 等带来源信息的认证尝试指标

    其中 METRICS_MEMORY_BREAKDOWN 与核心服务器的 memory_breakdown 诊断命令一一对应,将进程内存(连接 reader/writer/channel、各类队列进程)、ETS 表(quorum 队列 ETS、元数据存储 ETS)、二进制堆、原子表、消息索引等全部细分为独立 gauge,便于在 Grafana 中构建精细的内存看板。

    实战用法:

    # 抓取详细指标(包含上述所有细分指标)
    curl -s http://localhost:15692/metrics/detailed | grep rabbitmq_detailed

    注意:/metrics/detailed 返回的数据量与采集开销高于默认端点,建议仅在排查或调试时使用,常规监控仍使用默认的 /metrics 端点。该插件的完整指标说明可参考 metrics-detailed.md 与 metrics.md。


    Management 插件修复:设置 Topic 权限时交换机列表遵循当前虚拟主机

    问题现象:在 Management UI 中设置 topic 权限(topic permissions)时,交换机(exchange)下拉列表没有遵循当前选中的虚拟主机,导致跨 vhost 的交换机也会出现在列表中,可能引发误配置。该修复由 @LuisCusihuaman 贡献,对应 PR 编号为 #3545。

    背景:topic 权限用于限制特定用户对某 vhost 下交换机基于 routing key 的读写(publish/consume)能力。在 HTTP API 层面,Management 插件通过 rabbit_mgmt_dispatcher.erl 暴露了一组 topic 权限相关路由:

    /vhosts/:vhost/topic-permissions
    /users/:user/topic-permissions
    /topic-permissions
    /topic-permissions/:vhost/:user/:exchange

    这些路由由 rabbit_mgmt_wm_topic_permissions* 系列资源处理器实现。

    修复效果:3.9.8 后,UI 中设置 topic 权限时,交换机列表会严格限定在当前所选虚拟主机内,避免误将其他 vhost 的交换机配置到当前 vhost 的权限规则中。若通过 HTTP API 脚本化配置 topic 权限,请确保 URL 中的 :vhost 与 :exchange 属于同一虚拟主机。


    AWS Peer Discovery 插件增强:失败请求日志更详细

    变更内容:AWS Peer Discovery 插件现在会对失败的 AWS API 请求记录更多细节,便于排查节点发现失败的原因。该增强由 @tvhong-amazon (AWS) 贡献,对应 PR 编号为 #3579。

    从 rabbit_peer_discovery_aws.erl 的日志调用可以看出,插件的日志体系覆盖了从初始化、区域设置、自动扩缩组(Autoscaling Group)发现到 EC2 API 请求的各个环节:

    ?LOG_ERROR("Error fetching autoscaling group instance list: ~tp", [Reason]),
    …
    ?LOG_ERROR("Error fetching node list via EC2 API, request path: ~ts, error: ~tp", [Path, Reason]),
    …
    ?LOG_WARNING("Cannot discover any nodes because AWS tags are not configured!", []),

    3.9.8 之后,当 EC2 相关 API 请求失败时,日志会包含请求路径(request path)与具体错误原因,帮助运维人员快速区分是 IAM 权限不足、网络不可达还是参数配置错误。排查 AWS 节点发现问题时,可结合以下步骤:

  • 在节点日志中搜索 rabbit_peer_discovery_aws 相关条目,重点查看 Error fetching node list via EC2 API 与 Error fetching autoscaling group instance list 的上下文;
  • 确认 AWS 区域、标签、自动扩缩组等配置项(对应 schema 位于 rabbitmq_peer_discovery_aws 的 priv 目录);
  • 确认运行节点所在 EC2 实例的 IAM 角色具备 ec2:DescribeInstances、autoscaling:DescribeAutoScalingGroups 等必要权限。

  • Web STOMP 插件增强:STOMP-over-WebSockets 支持消费 Streams

    变更内容:STOMP-over-WebSockets 连接现在可以消费 RabbitMQ Streams 中的消息。对应 PR 编号为 #3509。

    背景:RabbitMQ Streams 是一种面向大规模消息处理场景的日志式队列类型(可参考 rabbitmq_stream/README.md),支持消息回溯与多消费者独立消费语义。此前 Web STOMP(基于浏览器的 STOMP 客户端,通过 WebSocket 接入)只能消费普通 AMQP 队列;3.9.8 扩展了其能力,使浏览器端 STOMP 客户端也能从 stream 消费消息。

    实战用法(结合 Web STOMP 与 Stream):

  • 确认已启用 rabbitmq_web_stomp 与 rabbitmq_stream 两个插件;
  • 通过 rabbitmq-stream 或 rabbitmqadmin 创建 stream 类型的队列;
  • 浏览器端 STOMP 客户端建立 WebSocket 连接后,向该 stream 队列发送 SUBSCRIBE 帧即可消费消息。
  • 该变更使 Web STOMP 场景(如浏览器实时仪表盘)可以直接对接 stream 的持久化、可回溯特性,而无需额外的桥接队列。Web STOMP 插件的连接与监听实现可参考 rabbit_web_stomp_connection_sup.erl 与 rabbit_web_stomp_listener.erl。


    依赖升级:Osiris 升级到 1.2.2

    本版本将 Stream 底层存储引擎 Osiris 从 1.2.0 升级到 1.2.2。Osiris 是 RabbitMQ Stream 子系统的核心依赖(在 rabbitmq_stream/Makefile 的依赖声明中可见),负责 stream 日志的底层读写与副本复制。该升级与前述 Stream 副本 IP 通告修复(osiris#53)直接相关,建议所有启用 Stream 的集群尽快升级。


    获取源码归档

    发布说明特别提醒:要获取完整发行版源码,请下载名为 rabbitmq-server-3.9.8.tar.xz 的归档文件,而不要使用 GitHub 自动生成的源码 tarball——前者才是包含全部 tier 1 插件(deps 目录下的内置插件)的完整发行源码。


    升级建议小结

    关注点3.9.8 的处理升级后建议动作
    mandatory 发布内存增长 已修复(#3560) 观察 channel 内存,尽量配合 publisher confirms
    memory_breakdown 读取失败 已修复(#3570) 用 –unit gigabytes 验证命令输出完整
    Stream 副本地址不可达 通告节点主机名(osiris#53) NAT/Docker 环境显式配置 stream.advertised_host
    /metrics/detailed 数据不足 暴露更多细分指标(#3520) 按需抓取 rabbitmq_detailed_ 前缀指标
    管理 UI topic 权限列表跨 vhost 已修复(#3545) 脚本配置时确保 vhost/exchange 一致
    AWS 发现失败难以定位 日志更详细(#3579) 关注 Error fetching node list via EC2 API 日志
    Web STOMP 无法消费 stream 已支持(#3509) 浏览器端 STOMP 可直接 SUBSCRIBE stream
    Osiris 存储引擎 升级至 1.2.2 Stream 集群尽快升级以获取副本修复

    对于 3.9.x 系列的后续维护版本,可在 release-notes 目录中持续追踪每个版本的变更明细。

    赞

    分享

    • 后端
    • 消息队列
    • 消息路由

    【免费下载链接】rabbitmq-server

    Open source RabbitMQ: core server and tier 1 (built-in) plugins

    项目地址:
    https://gitcode.com/gh_mirrors/ra/rabbitmq-server

    点击查看 免费下载

    上一篇:
    yuzu模拟器完全指南:免费畅玩Switch游戏的终极教程

    下一篇:
    Yii 2 框架完全指南:快速、安全、专业的 PHP 全栈框架入门与仓库导读

    创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » RabbitMQ 3.9.8 维护版本发布详解:核心服务器缺陷修复与插件增强全解析
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!