1、为什么会有 HTTP Rest 和 RPC 之间的选择呢?
问就是微服务,产品层面上,每个团队都可以单独完成服务的开发和部署,而无需与其他团队协调,以便产品可以在不同的时间和团队完成快速迭代。技术层面上,保证服务之间的隔离性,出现问题可以通过超时、熔断、限流、降级等技术保证服务之互不影响....诸多好处。
从一个服务拆分为多个服务,多个服务之间要进行通信,通信自然需要网络,这里就有一个选择题,应该选择7 层的 HTTP,还是基于 Socket 的 RPC 呢?
总的来说,如果没啥特殊需求的话 HTTP 完全能够满足 RPC 调用场景。HTTP 可以使用 pb、thrift 等紧凑的编码格式进行序列化和反序列化,也可以实现 RPC 的各种限流、熔断和降级,HTTP 高版本协议也是支持连接池复用的,也就是建立一定数量的连接不断开,并不会频繁的创建和销毁连接造成过多网络断链的性能损耗。如果非要找到一点区别,那就是传输协议,HTTP 会包含头信息,即使传递一个非常小的信息,也要包含一个头信息。
代码语言:javascript复制HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
<html>
<body>Hello World</body>
</html>
当然收到消息的一方还会有 response header,如上所使用的报文中有效字节数仅仅占约 30%,也就是70%的时间用于传输元数据废编码。当然实际情况下报文内容可能会比这个长,但是报头所占的比例也是非常可观的。
而如果使用基于 Socket 的 RPC 协议则更紧凑,可能不需要这些无效的信息传递。
2、为什么更多组织更倾向于选择 HTTP
HTTP 具有普适性,就像普通话一样,大家都能听得懂。HTTP 已经广为人知,特别是 JSON 格式,直接使用 HTTP 的 API 比 RPC 要更少了解一些业务编程领域之外的知识。之前本人在的公司就碰到过这个问题,出现了跨语言通信的问题,架构师说了句让我至今记忆犹新的话,我看了一天跨语言的 thrift 和 pb 才刚刚搞明白如何生成和使用,而且还要自己定义数据结构(太难了),还是用 HTTP 吧。
HTTP 更易于实验,在你的系统集成之前或之后,你可以通过 curl 或者浏览器进行测试 API 的正确性。
另外大多数的组织并不会因为 HTTP 网络协议而导致自身服务出现性能瓶颈,甚至根本不需要限流、重试、熔断和降级。所以,服务之间的调用选择 HTTP 看似愚蠢,但也有一定道理。
3、到底应该选择 HTTP 还是 RPC
原则上来说,南北流量(C端流量)一般使用 HTTP,东西流量(服务内部调用)更倾向于使用 RPC,比如常见的 Mysql、redis 的调用基本都是基于 Socket 的 RPC。
但 HTTP 和 RPC 早已你中有我,我中有你。无论选择谁都可以达到相同的目的。7 层的 HTTP 还是基于 Socket 的 RPC 只是一种网络传输方式,重要的是序列化格式、服务发现治理、限流、熔断、超时、重试.... 还有底层基础设施、链路追踪、日志、监控告警。虽然都可以实现,但每种技术的实际实现是存在一定差别的,基于不同编程语言实现、甚至各个组件的排列组合不同,维护代价也不一样,总而言之,无论选择谁需要花大量资源去落地,这个落地的代价是不可忽略的。
因此,如果当前的主要精力是业务规模扩张,尽量选择生态比较成熟的全套解决方案,比如编程语言以 Java 为主的可以选择 dubbo,spring cloud;存在跨语言场景的,可以选择 thrift,GRPC;或者直接使用基础设施 Kubernetes 网络管理能力,后期根据需要扩展服务内部流量治理。选择的过程不仅要考虑场景和业务价值,也要结合开发人员实际落地能力。关键是要选一套既要满足性能、自研扩展,又要满足简单运营维护的需要。