联合: 及时清除链路的缓存,并在缓存消息之前丢弃消息

作者: lukebakken创建于 2026年9月13日更新于 2026年9月13日
标签effort-mediumenhancementrabbitmq-federation

> [!注意] > 此问题由 Claude (Anthropic 的 Claude 代码) 在 @lukebakken 的指导下起草。代码引用已根据 #17238 分支进行验证。描述的工作已经存在于本地分支中;它缺少的只是测试覆盖率,这就是为什么它被从该 Pull Request 中删除的原因。#17238 缓冲了交付,直到下游节点有资源告警。作为其一部分编写了两项更改,然后又被删除,因为这两项都不需要关闭 #16670,也都不受测试的监测。### 排水响应能力`rabbit_federation_link_util:drain_buffer/4`在一个`handle_info`回调中转发了整个缓冲区。一个排水至`prefetch-count`消息的链接在中间什么都不回答:既不是`basic.ack`,也不是确认,也不是其下游通道死亡,也不是监督器关闭。在`ack-mode`为`on-confirm`时,它还对每个缓冲消息进行一次同步`amqp_channel:next_publish_seqno/1`调用,而不返回到其邮箱。方法是转发每个回调中的一个交付,并通过`continue_drain`消息重新装载。两个链接模块都不实现`prioritise_info/3`,因此`gen_server2`为每个消息设置优先级为 0,并将重新装载处理为已排队的任何内容,这就是让链接在排水期间回答这些消息的原因。它要求在排水期间到达的交付也被缓冲起来,否则它将被转发到尚未排队的消息之上。### 预缓冲丢弃过滤器`max-hops`和循环检查在`forward/9`中进行评估,对于缓冲消息在排水时只运行一次。链接始终要丢弃的消息因此占用缓冲区空间,并在上游的预取窗口中占据一个位置,直到那时。在缓冲之前做出决定还意味着每个交付两次解析集群名称,因此它应该在两次检查中解析一次,并通过两次检查线程化。`rabbit_nodes:cluster_name/0`在`cluster_name`运行时参数设置时才读取 ETS,否则将解析本地主机名。### 为什么它被删除 没有任何人观察到响应能力。恢复整个缓冲区循环将 `exchange_alarm_SUITE` 和 `queue_alarm_SUITE` 中的每个测试都置为绿色,因此该属性依赖于 `gen_server2` 的消息顺序,而不是依赖于一个断言。队列链路的顺序保护也未被发现:队列联合只在下游队列为空且有活动消费者时从上游拉取,因此在下游排水期间不会消费第二批数据。### 该做什么 恢复这两项更改并添加它们缺少的覆盖:1. 断言链接在排水期间回答了某些内容,例如确认,确认或状态更改。这是最困难的部分,也是工作推迟的原因。2. 对队列链路的顺序保护进行覆盖,这需要一种方法来让队列联合在排水期间消费第二批数据。在交换机端的顺序已通过 `deliveries_during_a_drain_keep_their_place` 进行了覆盖:在告警下缓冲了 200 个消息,然后发布到交换机中,并将其排序到正确的位置。

内容来源: rabbitmq/rabbitmq-server