yuqi-zheng

Ray 异步基础设施(二):事件循环可观测性与混沌测试


Ray 异步基础设施系列第二篇。← 上一篇:Asio 的角色与 instrumented_io_context · 下一篇:线程池与定时器 →


1. 滞后探测:LagProbeLoop

设计原理

LagProbeLoop 通过递归投递探针任务,测量任务从投递到实际执行的时间差——即事件循环的当前排队延迟(lag)。

void LagProbeLoop(instrumented_io_context &io_context, int64_t interval_ms, ...) {
  auto begin = std::chrono::steady_clock::now();
  io_context.post([begin, ...] {
    auto end = std::chrono::steady_clock::now();
    auto lag = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin);
    // 上报指标
    io_context.io_context_event_loop_lag_ms_gauge_metric.Record(lag.count(), ...);
    // 计算下次探测时间:若已经滞后,立即再探
    auto delay = interval_ms - lag.count();
    if (delay <= 0) {
      LagProbeLoop(io_context, interval_ms, ...);
    } else {
      execute_after(io_context, [&] { LagProbeLoop(...); }, delay);
    }
  });
}

探针的逻辑很优雅:beginpost 前记录,end 在回调内记录,差值即为该任务在队列中等待的时间。若滞后已超过探测间隔,下次探测立即发起,确保监控不被自身的延迟所掩盖。

启动时机

instrumented_io_context 构造时,若 emit_metrics == true 则通过 post 投递首次探针——确保 io_context::run() 启动后才开始计时。

监控指标

  • 指标名io_context_event_loop_lag_ms
  • 类型:Gauge(瞬时值)
  • 告警含义:持续偏高意味着事件循环过载。心跳任务被延迟投递 → GCS 误判节点死亡 → 触发不必要的故障恢复。

2. 混沌延迟注入:asio_chaos

目的

分布式系统中有一类 bug 只在特定时序下出现,正常测试很难触发。asio_chaos 允许对任意 post 调用注入随机延迟,人为制造时序抖动,复现这类 bug。

配置方式

export RAY_testing_asio_delay_us="Heartbeat=1000:2000,ObjectPull=50000:100000,*=0:100"
  • 格式:方法名=最小延迟us:最大延迟us
  • * 为通配符,匹配所有未显式指定的方法

上面的配置含义:

  • Heartbeat 回调随机延迟 1~2ms
  • ObjectPull 回调随机延迟 50~100ms(模拟网络拥塞)
  • 其他所有回调随机延迟 0~100μs

实现机制

instrumented_io_context::post 内部:

int64_t extra_delay = ray::asio::testing::GetDelayUs(name);
// 将立即入队的任务转为定时器延迟投递
execute_after(io_context, std::move(handler), extra_delay);

GetDelayUs 从全局 DelayManager 单例(由环境变量初始化)查找该方法名对应的随机延迟范围,返回一个随机值。

注意事项

  • 仅用于测试,生产环境不得开启
  • 启用后会有 ERROR 级别日志:“Delaying method …”
  • 通过判断环境变量是否为空来禁用,零运行时开销

3. 两者的协作关系

LagProbeLoop      → 发现事件循环过载
asio_chaos        → 主动制造过载,测试系统在过载下的正确性

前者是被动监控,后者是主动压测。两者共同构成 Ray 异步运行时可观测性与可测试性的基础。


总结

  • LagProbeLoop 是 Ray 事件循环的内置健康探针,lag 持续升高是过载的早期信号。
  • asio_chaos 通过环境变量注入随机延迟,是复现分布式时序 bug 的有效工具。
  • 两者设计上都对生产环境零开销:前者仅在 emit_metrics=true 时启用,后者仅在环境变量非空时生效。

下一篇:线程池 IOServicePool 与定时器 PeriodicalRunner →