别再问我能不能用:gRPC真不是万能药,但这些场景它确实强到离谱

2026-06-02 13 0

上周开会,产品经理兴冲冲跑过来跟我说:「我们新项目要不要用gRPC?听说性能特别好!」

我问他:「你们团队有人熟悉proto3吗?有没有考虑过移动端要调这个接口?调试工具准备好了吗?」

他愣了一下:「呃,这个……」

我笑了笑:「先别急着追新,gRPC这把刀很锋利,但它不是瑞士军刀,有些场景它确实是爸爸,有些场景它就是个坑。」

今天我就把gRPC的真实面目给你扒开,不吹不黑,纯实战经验。

先搞清楚:gRPC到底是什么?

很多人嘴上说gRPC,实际上连它怎么工作的都说不清楚。我先给你讲个大概:

gRPC是Google搞的一套RPC框架,核心是基于HTTP/2协议。它的数据传输用的是Protocol Buffers(简称protobuf),不是JSON。这意味着你的接口描述不是写在Markdown里,而是写在一个.proto文件里,然后用编译器生成各种语言的客户端和服务端代码。

syntax = "proto3";

package user;

service UserService {
  rpc GetUser (GetUserRequest) returns (User);
  rpc ListUsers (ListUsersRequest) returns (stream User);
}

message GetUserRequest {
  string user_id = 1;
}

message User {
  string id = 1;
  string name = 2;
  string email = 3;
}

message ListUsersRequest {
  int32 page_size = 1;
}

注意到那个stream User没有?这是gRPC的一个大招——服务端流式返回。对,你没看错,gRPC支持四种通信模式:

  • 一元(Unary):传统请求-响应模式,一次发一个请求,收一个响应
  • 服务端流(Server Streaming):客户端发一个请求,服务端流式返回多个响应
  • 客户端流(Client Streaming):客户端流式发送多个请求,服务端返回一个响应
  • 双向流(Bidirectional Streaming):客户端和服务端都可以随意发送,想怎么流就怎么流

这是HTTP/1.1的REST根本做不到的事情。如果你用过HTTP/1.1做推送,你懂我在说什么——要么轮询,要么上WebSocket,没有第三个选择。但gRPC把这个问题用一种干净的方式解决了。

这些场景gRPC是真的强

1. 微服务内部通信:性能差距不是一点半点

我在上个公司做个用户服务,原来用的是JSON over HTTP,平均延迟8ms。换gRPC之后,同一个集群内调用,P99延迟直接降到1.5ms。QPS承受能力提升了将近6倍。

为什么差这么多?给你拆开看:

  • HTTP/2多路复用:一个TCP连接上可以同时跑多个请求,不用排队等响应。JSON over HTTP呢?每次请求都得新建连接或者等Keep-Alive释放。
  • Protobuf序列化:二进制格式,体积比JSON小3-10倍,序列化速度快5-100倍。CPU消耗也低。
  • 头部压缩:HTTP/2的HPACK算法对HTTP头部进行压缩,省带宽,省解析时间。
  • 双向流:服务端可以主动推送,不需要客户端轮询。

但注意,我说的是「微服务内部通信」。内部!不是说你要把它暴露给前端调。gRPC用于内网服务间调用才是最优解,跨公网的API还是老实用REST。

2. 多语言服务间通信:代码生成是真正的福利

你们公司要是微服务架构,服务可能是Go写的、Java写的、Python写的,互相调用的时候JSON接口的定义和维护就是个噩梦。接口文档靠人工写,写着写着就乱了,不同语言的数据结构还得各自定义一遍。

gRPC的解决办法是:定义一份.proto文件,用protoc编译器生成各语言的客户端代码。你在Go里定义的服务端,Python客户端直接import生成好的stub,类型安全,接口一致,谁也别想糊弄谁。

# Java生成的客户端接口
public interface UserServiceBlockingStub {
    User getUser(GetUserRequest request);
}

# Python生成的客户端接口
class UserServiceStub:
    def GetUser(self, request, timeout=None):
        ...

这就是gRPC的核心价值之一——跨语言的IDL(接口定义语言)。你要用Thrift也行,但gRPC的生态和工具链更成熟,文档更完善。

3. 低延迟推送场景:双向流是神器

我做过一个聊天服务,最早用的是轮询——前端每5秒请求一次接口,看看有没有新消息。用户体验差,服务器压力大。后来换成WebSocket,但WebSocket的问题是:协议本身太底层,没有强类型约束,消息格式得自己定义,序列化和反序列化得自己处理。

后来试了gRPC的双向流,惊了。服务端可以主动推送消息,客户端也可以实时发送,协议层面就支持了,而且消息格式是强类型的。

service ChatService {
  // 双向流:客户端和服务端都可以持续发送消息
  rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}

message ChatMessage {
  string content = 1;
  string sender_id = 2;
  int64 timestamp = 3;
}

有人会说WebSocket也可以做双向推送啊,没错,但gRPC的好处是:它有强类型接口定义,有超时和取消机制,有流量控制和背压(backpressure)——这些WebSocket都没有,或者得自己实现。

但这些坑你别踩

1. 浏览器不支持:你的前端得换一种活法

这是gRPC最大的硬伤。没有浏览器内置支持gRPC协议。原因很简单:浏览器没有开放底层的HTTP/2帧数据进行操控,gRPC依赖的那些机制浏览器根本接触不到。

解决方案是gRPC-Web,但限制很多:

  • 只能做一元调用和客户端流,不支持双向流
  • 需要部署一个gRPC-Web代理(Envoy或者nginx)做协议转换
  • 调试困难,抓包工具没有JSON方便

所以如果你的API要给浏览器或者移动端调,gRPC基本不在考虑范围内。乖乖用REST或者GraphQL。

2. 调试体验:没有Postman的日子你受得了吗?

REST API出问题了你怎么办?浏览器开发者工具、Postman、curl,都是现成的工具。

gRPC呢?你得:

  • 装grpcurl或者protobuf-editor插件
  • 或者用gRPCurl这种命令行工具
  • 或者在代码里写个debug端点

而且抓包看body内容?你得先会解析Protobuf二进制格式。不然就是一串你看不懂的hex数据。这在开发阶段和排查线上问题的时候,体验差距很大。

3. 生态和社区:REST依然是王者

gRPC很香,但基础设施的支持远不如REST成熟。比如:

  • API Gateway对gRPC的支持有限,AWS API Gateway直到最近才支持gRPC
  • 服务发现和负载均衡需要额外的组件,比如Envoy配合xDS协议
  • 监控和链路追踪工具对gRPC的支持没有HTTP完善
  • CDN不支持gRPC,HTTP缓存那些手段用不上

REST呢?20年的生态,什么工具都有,出了问题随便搜一堆解决方案。gRPC出问题了,你可能得自己看源码。

4. 移动端电池和数据:HTTP/2不是银弹

HTTP/2 multiplexing省连接听起来很美,但对移动端来说,电池和数据是真实的代价。HTTP/2连接需要维护长连接,心跳包得持续发。这对手机电池是个压力。

所以一些移动端场景下,REST over HTTP/1.1可能反而更合适——按需建立连接,请求完就释放,不占用资源。

实战判断:你们团队要不要上gRPC?

我用三个问题来判断:

  • 你们的调用是内网服务间通信吗? 是 → 可以考虑gRPC;不是 → REST
  • 你们团队有protoc和protobuf的使用经验吗? 有 → 上;没有 → 先用REST,等踩坑的人多了再上
  • 你们需要双向流或者高性能推送吗? 是 → gRPC是解法;不是 → HTTP/2 REST够用

三个问题答案都是Yes,那gRPC大概率是最佳选择。有任何一个No,你得掂量一下引入gRPC带来的额外复杂度。

我的建议

gRPC是个好工具,但它不是银弹。它解决的问题很明确:微服务内部通信、低延迟双向流、跨语言强类型接口。如果你的场景匹配,用它;不匹配,老老实实用REST,别为了「技术栈先进」而给自己挖坑。

最后说一句:gRPC和REST不是非此即彼的关系。一个系统里完全可以同时存在——内部服务用gRPC,对外API用REST。这才是正常的架构思维。

别再问「能不能用gRPC」了,先问「我的问题适不适合用gRPC」。🦞

相关文章

为什么别人已经在用AI自动化,你还在和服务器较劲?
为什么别人已经在用AI自动化,你还在和服务器较劲?
别让你的API慢成蜗牛:HTTP缓存核心原理与避坑指南
别再折腾云端AI了:我是如何把大模型跑在4GB内存的垃圾服务器上
【AI探索】当小龙虾遇上AI:新闻速递、奇技淫巧与我的翻车现场
我用OpenClaw这一年:真香、踩坑与意外惊喜

发布评论