配置丢包注入
丢包注入是在生产环境替你完成之前,主动给恢复路径施压的手段。Java media driver 允许你在 JVM 启动时通过系统属性把丢包率固化进 driver——确定且可复现,这正是自动化测试和 CI 所需要的。
本页讲的是如何接好这种静态丢包注入并读出其效果。至于 Aeron 究竟如何检测间隙并完成重传,请参阅 The Aeron Files。关于同一套 io.aeron.driver.ext 机制以及 CUBIC 拥塞控制,参见 丢包注入与 CUBIC 拥塞控制。
通过系统属性进行静态配置
Section titled “通过系统属性进行静态配置”在 JVM 启动时设置丢包参数。这些属性由 DebugChannelEndpointConfiguration 消费。
只设这些 rate 属性是不够的——默认的 channel endpoint 从不查询丢包生成器。你必须先换上 debug endpoint,这是每一侧各自独立的属性:
-Daeron.ReceiveChannelEndpoint.supplier=io.aeron.driver.ext.DebugReceiveChannelEndpointSupplier-Daeron.SendChannelEndpoint.supplier=io.aeron.driver.ext.DebugSendChannelEndpointSupplier| 属性 | 说明 |
|---|---|
aeron.debug.receive.data.loss.rate | 接收侧数据丢包率(0.0 - 1.0) |
aeron.debug.receive.data.loss.seed | 接收侧数据丢包 RNG 的种子 |
aeron.debug.receive.control.loss.rate | 接收侧控制丢包率 |
aeron.debug.receive.control.loss.seed | 接收侧控制丢包 RNG 的种子 |
aeron.debug.send.data.loss.rate | 发送侧数据丢包率 |
aeron.debug.send.data.loss.seed | 发送侧数据丢包 RNG 的种子 |
aeron.debug.send.control.loss.rate | 发送侧控制丢包率 |
aeron.debug.send.control.loss.seed | 发送侧控制丢包 RNG 的种子 |
你由此获得四个相互独立的丢包旋钮:发送/接收与数据/控制的交叉组合。最有意思的测试往往来自非对称配置。
让丢包注入更贴近真实的四个设计要点
Section titled “让丢包注入更贴近真实的四个设计要点”整个框架建立在四项有意为之的设计决策之上。
1. 数据丢包与控制丢包相互独立
Section titled “1. 数据丢包与控制丢包相互独立”数据包与控制包(状态消息、NAK、RTT)拥有各自独立的丢包生成器。这让你能够测试”数据能通过,但 NAK 丢失”的场景。该场景考验的是:当系统的恢复机制本身受损时,它还能否恢复。
2. 两种丢包模型——随机 rate vs. 编排间隙
Section titled “2. 两种丢包模型——随机 rate vs. 编排间隙”上面的 *.loss.rate 属性接的是 RandomLossGenerator,它逐帧的判定就是 random.nextDouble() <= lossRate。它不具备重传感知:在给定 rate 下,它会以同样的 rate 丢掉重传帧——这对有损链路是真实的,但意味着高 rate 会让重传不断累积。
这个包还提供了 FixedLossGenerator 和 MultiGapLossGenerator,它们确实具备重传感知:按 stream 和 session 跟踪哪些帧已经被丢弃,并放行其重传。若没有这一点,“丢弃第 42 号帧”的规则也会把第 42 号帧的重传一并丢掉——从而制造出无法恢复的间隙和无限的重传循环。但系统属性这套机制从不实例化这两者——它们用于编程式搭建(例如 JavaTestMediaDriver)。需要均匀随机丢包时用这些属性;需要编排好的、具备重传感知的间隙模式时,走编程式路径。
3. 种子让运行结果可确定
Section titled “3. 种子让运行结果可确定”每个随机丢包生成器都接受一个种子。固定的种子意味着相同的丢包模式,也就意味着相同的测试结果。正是这一点让那些看似不稳定的测试变得可复现——这对 CI/CD 至关重要,因为你需要一致的通过/失败行为。
4. NAK 合并可被关闭
Section titled “4. NAK 合并可被关闭”调用 dontCoalesceNaksOnReceiverByDefault() 即可将 NAK 延迟设为零。NAK 会被立即发送,而不必等待合并窗口。这能在不改变丢包行为的前提下,加快测试中的重传速度。
注入丢包时需关注的计数器
Section titled “注入丢包时需关注的计数器”下面这四个计数器能告诉你:系统如何检测丢包、如何恢复,以及为此付出了多大代价。
| 计数器 | 它告诉你什么 |
|---|---|
| NAK messages sent/received | 丢包发生时会出现尖峰——反映检测速度 |
| Retransmits sent | 反映恢复活动——有多少带宽用于恢复 |
| Publisher pos vs Subscriber pos | 丢包下间隙增大——反映 subscriber 落后了多远 |
| Bytes sent/received | 吞吐影响——量化丢包的代价 |
丢包如何映射到 p50、p99 与吞吐量
Section titled “丢包如何映射到 p50、p99 与吞吐量”丢包注入会撼动这三个数字,但程度并不均衡。
- 吞吐量受到的冲击最为直接。重传发送与新鲜数据争抢同一份带宽,而 bytes sent/received 计数器会实时量化这一代价。
- p99 与长尾最先被拉长。一个被丢弃的帧会让 subscriber 停滞,直到检测与重传完成。NAK 检测速度和合并窗口决定了这一停滞持续多久——这也正是
dontCoalesceNaksOnReceiverByDefault()能缩短它的原因。 - p50 在低丢包率下相对稳定,因为大多数消息一次就能送达。只有当丢包率攀升到足以影响中位投递时,它才会劣化。
本站与 Adaptive Financial Consulting Limited 或 Aeron 项目无任何关联,未获其背书或赞助。 Aeron 是 Adaptive Financial Consulting Limited 的注册商标。
Aeron 是 Adaptive Financial Consulting Limited 在英国及其他国家/地区的商标。