You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需端口转发的Scheduler-worker集群:GRPC架构可行性咨询

核心结论

直接让Scheduler主动调用NAT后的Worker gRPC API行不通——NAT设备会直接丢弃外部发起的未关联连接请求。但完全可以通过反向流式长连接的方式实现你要的效果,完美契合“Worker主动订阅Scheduler”的需求。

可行架构方案(基于gRPC双向流)

我建议采用「Worker主动发起与Scheduler的长连接,复用该连接实现双向通信」的模式,具体设计如下:

1. 核心gRPC服务定义

Scheduler端服务(Worker主动连接)

service SchedulerService {
  // Worker注册并建立双向流:Worker发状态/结果,Scheduler下任务/指令
  rpc RegisterWorker(stream WorkerMessage) returns (stream SchedulerMessage);
}

message WorkerMessage {
  oneof payload {
    WorkerStatus status = 1;       // 定期上报资源状态
    TaskResult result = 2;         // 任务结果流
    FileDownloadAck download_ack = 3; // 文件下载完成确认
  }
}

message SchedulerMessage {
  oneof payload {
    TaskAssignment task = 1;       // 下发任务
    CancelTask cancel = 2;         // 取消任务
    FileDownloadRequest download = 3; // 要求下载指定测试文件
  }
}

配套核心数据结构(简化版)

message WorkerStatus {
  string worker_id = 1;
  int32 running_tasks = 2;
  float cpu_usage = 3;
  float memory_usage = 4;
  repeated string cached_files = 5; // 已缓存的测试文件列表
  repeated TaskType supported_types = 6; // 支持的任务类型
}

message TaskAssignment {
  string task_id = 1;
  TaskType type = 2;
  string code_content = 3;
  string required_file = 4; // 关联的测试文件
}

enum TaskType {
  INTERACTIVE = 0;
  PRESET_TEST = 1;
}

2. 关键流程实现

  • Worker注册与保活:Worker启动后主动连Scheduler,发起RegisterWorker双向流,定期发WorkerStatus当心跳;Scheduler如果长时间没收到心跳,直接标记该Worker离线。
  • 任务分发逻辑:Scheduler根据任务类型、Worker已缓存的文件、当前运行任务数(不超过16),通过已建立的流下发TaskAssignment。
  • 任务执行与结果返回:Worker拿到任务后执行,把实时状态、结果(包括交互式任务的控制台流)通过同一个流回传给Scheduler。
  • 文件缓存控制:Scheduler下发任务前先检查Worker的cached_files,如果没对应文件,先发FileDownloadRequest,Worker下载完成后回传FileDownloadAck,Scheduler再下发任务。

3. 适配你的特殊需求

  • 多类型专用Worker:Worker在WorkerStatus里上报supported_types,Scheduler按任务类型精准匹配分发。
  • 大文件传输:要么用gRPC流式传输,要么让Scheduler在FileDownloadRequest里给个临时可访问的下载地址(比如Scheduler本地启个简单HTTP服务),Worker直接走HTTP下载,不占gRPC连接带宽。
  • 并发任务控制:Scheduler严格根据Worker上报的running_tasks控制下发数量,确保不超过16个的上限。
替代方案(非必要不推荐)

如果非要模拟“Scheduler调用Worker API”的体验,可以试试gRPC反向代理或者穿透服务,但会增加系统复杂度:

  • 让Worker启动时主动向Scheduler注册,同时把自身gRPC服务暴露到STUN/TURN穿透网关,但要额外维护网关服务。
  • 在Scheduler侧做反向代理,通过Worker发起的长连接转发对Worker API的调用请求,本质还是复用反向连接。
Go语言实现注意事项
  • 配置gRPC Keepalive:给Worker(客户端)设心跳间隔,Scheduler(服务端)设超时检测,确保长连接稳定。
  • 重连逻辑:Worker侧加自动重连,重连时重新注册身份,避免连接断开后失联。
  • 流消息有序性:gRPC流是有序的,不用额外处理消息顺序,直接按业务逻辑发送就行。
  • 任务隔离:Worker侧每个任务用单独进程或轻量容器隔离,防止单个任务崩溃影响整个Worker。

内容的提问来源于stack exchange,提问作者Krišjānis Petručeņa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 01:55:11