Prompts-MCP 686 skills · ai / design / design-pattern / framework / fundamentals / habit / lang / tech-selection /mcp/sse
framework framework/grpc/four-call-types.md medium

grpc-four-call-types

gRPC 四种调用方式 — 一元 / 服务端流 / 客户端流 / 双向流,及各自适用场景与选型。Use when 定义 rpc 方法 / 选一元还是流式 / 设计推送或上传接口时。

流式调用服务端流双向流streamstreamobserverunary
paths
  • *.java
  • *.proto

gRPC · 四种调用方式与选型

本条只管「选哪种调用方式」。message/字段怎么定义见 proto-definition.md;超时与错误见 error-and-deadline.md

规则

调用方式 proto 写法 适用场景
一元 unary rpc M(Req) returns (Resp) 普通请求-响应:查询、单次写。默认首选
服务端流 server-streaming rpc M(Req) returns (stream Resp) 一次请求、多条结果陆续返回:大结果集分批、订阅推送、进度上报
客户端流 client-streaming rpc M(stream Req) returns (Resp) 多条上行、单次汇总返回:批量/分片上传、客户端聚合后服务端算一次
双向流 bidirectional rpc M(stream Req) returns (stream Resp) 长连接双向实时交互:聊天、协同、实时行情、心跳

选型口诀:默认用一元;只在「结果太大/要持续推/要长连双向」时才上流式 —— 流式更复杂(背压、半关闭、错误中途)。

正例

service OrderService {
  rpc GetById(GetByIdReq) returns (OrderDTO);              // 一元
  rpc ListByDay(ListReq) returns (stream OrderDTO);        // 服务端流:大结果集分批
  rpc Import(stream OrderDTO) returns (ImportResult);      // 客户端流:批量上传
  rpc Sync(stream Event) returns (stream Event);           // 双向流:实时同步
}
// 服务端流:逐条 onNext,结束 onCompleted
@Override
public void listByDay(ListReq req, StreamObserver<OrderDTO> obs) {
    orderRepo.streamByDay(req.getDay()).forEach(o -> obs.onNext(toDTO(o)));
    obs.onCompleted();
}

反例

❌ 用一元接口返回十万条的大 list:单条响应体过大,反序列化与内存峰值爆炸 → 应改服务端流分批。

❌ 用轮询一元接口模拟实时推送:高频空轮询浪费连接与 CPU → 实时推送用服务端流或双向流。

❌ 简单查询硬上双向流:徒增半关闭/背压/错误处理复杂度,得不偿失。

自检

  • [ ] 普通请求-响应优先用了一元,没有过度流式化?
  • [ ] 大结果集 / 持续推送用了服务端流?
  • [ ] 批量上传 / 客户端聚合用了客户端流?
  • [ ] 长连双向实时交互才用双向流?

相关