gRPC 和 RESTful 的比较是两套 API 风格的比较。虽然 gRPC 采取了 HTTP2 ,但这并不代表 RESTful 不能基于 HTTP2 ,但 RESTful 也可以采用 HTTP1 ,这是因为二者的着眼点有所不同。 gRPC 采用了二进制的方式进行传输,目的是为了更快、更多样化的传输数据,而 RESTful 采用 JSON 作为传输数据的格式,相应的也就牺牲了速度与传输数据的多样化,但同时收获了数据的可读性。我们深入进去就会发现,为了数据的可读性, RESTful 必须对数据进行冗余,以此来保证传输数据的可读性,而 gRPC 则对数据进行压缩,以保证大数据能够被更快的传输过去,但同时加深了调试的难度。因此,当我们传输的数据越大的时候, gRPC 就越具有优势,因为当数据量过大是,可读性反而成了拖累,速度会反向影响调试和可读性。且二进制对于计算机来说是比 JSON 结构好读的, JSON 解析必然是一大负担,当 JSON 足够大时,解析也会变得十分困难,而栈帧的结构对于计算机来说更好。

虽然如此,但当你用 Python 或者 NodeJS 写一个 RESTful 的服务,总比写一个 gRPC 服务要容易得多。的确,你要完成一个 gRPC ,你必须书写 proto ,还要生成代码,显得十分累赘。但各个 RPC 之间通过 proto 可以确认彼此间的接口调用,同时,不同语言的项目可以通过 proto 统一类型,而不必理解各个语言间的差异,这是十分好的。而且,对于静态语言来说,类型是必须书写的,使用 gRPC 提供的工具自动生成代码也节省了好多功夫。毕竟,像 Java 之类的语言做客户端处理 JSON ,比起 NodeJS 来说实在差太多。

但对于 gRPC 来说,还有一点十分重要,就是负载均衡。负载均衡的问题其实是 HTTP2 带来的, HTTP2 的多路复用、 Server Push 为 gRPC 所用,并在服务间创建一条长连接。显然,负载失衡是必然的问题,为了处理负载失衡的问题,一般会创建 Load Balancer 来处理。但 RESTful 由于并没有长连接需要保持,且不复用,所以反而没有这个问题。使用 RESTful ,我们可以直接使用 NGINX 之类的代理服务进行负载均衡。在 gRPC ,但如果我们仍然想要 gRPC 给我们带来优点的话,我们必须考虑自己写一个 Load Balancer 。

综上所述, gRPC 对比 RESTful 是有诸多优点的:

  1. 速度快,传输体积小,对于计算机来说解析方便。理论上可传输更大体积。
  2. 统一不同服务提供者和服务消费者对于接口的描述,自动生成代码省去了一些语言编码的功夫。

但缺点则对能力不足的技术团队颇有挑战:

  1. 负载均衡问题是一点,需要有一定技术力去实现。横向对比 thrift ,则缺少了服务发现、连接池等能力,但 RESTful 本身也没有这些,且 thrift 跟 HTTP 无关。

对于技术力不足的团队来说,用 RESTful 构建 RPC 不失为一种良好的选择。