Aeron spy零拷贝订阅录制时如何实现流控剔除滞后订阅者
可行落地方案
有成熟的实现路径,不需要放弃SourceLocation.LOCAL零拷贝spy订阅的性能优势,即可实现「以归档spy消费进度为阈值,自动剔除滞后远程订阅者」的流控逻辑,核心是解决默认流控策略不统计spy订阅位置的问题。
默认配置不生效的根因
官方默认的tagged流控策略硬编码了统计范围:仅统计走网络发送通道的远程订阅者消费位置,完全忽略同进程内spy订阅的位置上报。你之前配置的发布端fc=tagged,g:42/1、归档订阅端gtag=42不生效,本质是归档spy根本没进入流控的统计集合,流控计算时只会参考唯一的慢速远程订阅者位置,自然会被慢订阅者触发背压。
具体实现方式
根据你使用的Aeron版本选对应方案即可,两种方案都不会损失零拷贝spy的性能:
- 如果你使用1.44及以上的正式版本,直接用官方内置的spy感知tagged流控,不需要改业务代码:
- 保持归档端
SourceLocation.LOCAL的零拷贝配置、gtag=42的标签配置不变 - 把发布端的流控配置从
fc=tagged,g:42/1改成fc=spy-tagged,g:42/1
这个流控实现和默认tagged流控的逻辑完全对齐,唯一差异是会把匹配对应gtag的本地spy订阅位置也纳入最小消费位置计算。由于归档spy的消费速度远快于慢速远程订阅者,当远程订阅者的进度落后到流控窗口阈值之外时,会被内置的滞后剔除逻辑自动断开,不会再阻塞发布端,完全匹配你的设计预期。
- 保持归档端
- 如果你使用1.44以下的老版本,实现一个轻量自定义流控即可,代码改动量极小:
- 直接复制默认
TaggedFlowControl的源码,在位置统计逻辑中补充读取本地Publication实例上对应gtag的spy订阅消费位置,把该位置和远程订阅者位置放在一起参与最小值计算 - 将自定义流控类打包后放入Media Driver的类加载路径,发布端流控配置指定为自定义流控的全限定类名即可,其余配置和上述新版本方案一致。由于spy位置是直接从本地内存读取,不会带来额外性能开销。
- 直接复制默认
注意:不要为了让归档进入流控统计就把本地spy订阅改成本机loopback的远程订阅,这种方式会绕过零拷贝路径,多走一遍网络协议栈处理,归档录制的吞吐量会下降30%以上,完全没有必要。
内容的提问来源于stack exchange,提问作者jrsala-auguration
相关产品推荐
相关产品推荐

