yuqi-zheng

Ray 异步基础设施(四):gRPC 与 Asio 的协作模式


Ray 异步基础设施系列第四篇。← 上一篇:线程池与定时器 · 下一篇:GCS 线程隔离设计 →


1. 分层架构

┌─────────────────────────────────────────────────────────────┐
│                  业务逻辑层(无锁串行)                       │
│          GcsNodeManager::HandleRegisterNode 等              │
└─────────────────────────────┬───────────────────────────────┘
                              │ post()
┌─────────────────────────────▼───────────────────────────────┐
│                  Asio 层(单线程事件循环)                    │
│     instrumented_io_context(如 "node_manager_io_context") │
└─────────────────────────────┬───────────────────────────────┘
                              │ 回调触发
┌─────────────────────────────▼───────────────────────────────┐
│                  gRPC 层(多线程网络 I/O)                    │
│            GrpcServer, CompletionQueue 线程池               │
└─────────────────────────────────────────────────────────────┘

关键原则:gRPC 线程负责收包,Asio 线程负责处理。两者通过 post 解耦,各司其职。


2. GrpcServer 的核心机制

完成队列与线程池

cqs_.resize(num_threads_);  // 每个线程一个 CompletionQueue

GrpcServer 启动 N 个线程,每个线程驱动一个 CompletionQueue。gRPC 请求到达时,由某个 CompletionQueue 线程完成网络读取和 Protobuf 反序列化。

请求到业务的桥接:ServerCall

每个 RPC 方法对应一个 ServerCallFactory(通过宏 RPC_SERVICE_HANDLER 生成)。

gRPC 线程收到请求后,ServerCall 对象被创建,但不直接调用业务函数,而是:

main_service_.post([this, request, reply, callback] {
    service_handler_->HandleXXX(request, reply, callback);
}, "HandleXXX");

一行 post 将控制权从 gRPC 线程转交给 Asio 事件循环。业务逻辑从此在单线程上串行执行。

RPC_SERVICE_HANDLER

#define RPC_SERVICE_HANDLER(SERVICE, HANDLER, MAX_ACTIVE_RPCS) ...

该宏为指定的 gRPC 方法自动生成 ServerCallFactory,绑定:

  • 请求/响应的 Protobuf 类型
  • 最大并发 RPC 数(过载保护)
  • 目标业务处理函数

3. 完整流程:以 RegisterNode 为例

Raylet ──(gRPC)──► GCS GrpcServer


            CompletionQueue 线程接收请求,反序列化


            创建 ServerCall 对象

                        │ post 到 node_manager_io_context

         ┌──────────────────────────────┐
         │ instrumented_io_context 队列 │
         └──────────────┬───────────────┘


      专用线程执行 GcsNodeManager::HandleRegisterNode


             业务逻辑完成,返回响应给 Raylet

整个流程中,业务逻辑(HandleRegisterNode)始终在 node_manager_io_context 的专用线程上运行,无需任何锁。


4. 设计优势

维度效果
并发网络 I/OgRPC 线程池多核并行,高吞吐
业务逻辑安全Asio 单线程串行化,无锁编程
故障隔离不同模块可绑定不同 io_context,一个模块慢不影响其他
可观测性每个 io_context 独立监控滞后(见第二篇)

总结

  • Ray 的 gRPC 服务不直接执行业务逻辑,而是将逻辑 post 给 Asio 事件循环。
  • 这种”前台多线程收发包,后台单线程处理”的模式是 Ray 高并发、高稳定性的核心架构决策。
  • ServerCall + RPC_SERVICE_HANDLER 宏是实现这一桥接的关键机制。

下一篇:GCS 模块级线程隔离设计 →