rpc比http好吗,缪论?
是什么,如何理解
RPC(Remote Procedure Call) 直译就是远程过程调用
HTTP(HyperText Transfer Protorl) 直译就是超文本传输协议
RPC和HTTP都是 请求-响应协议,但是因为出现的时机、设计理念、约定协议、效率、应用范围、使用规则等不同,所以是不同的名字,本质都是为了分布式系统间的通信而生,是一种应用层通信(请求-响应)协议(从OSI网络模型来看)。
RPC是 Bruce Jay Nelson 在1981年创造的术语,HTTP是在1990年左右产生的(可以参看维基百科)
RPC协议 和 RPC,到底叫什么?RPC协议=RPC
HTTP协议、HTTP,到底叫什么?HTTP协议=HTTP
RPC|HTTP只是大家的简称
1、HTTP协议不仅仅只有协议,还有超文本,传输,以及很多功能(比如编解码、面试经常背的各种参数的作用)
2、RPC协议也不仅仅只有协议,还有 编解码,服务注册发现,负载均衡等
RPC协议本质上定义了一种通信的流程,而具体的实现技术是没有约束的,每一种RPC框架都有自己的实现方式,我认为HTTP也是RPC的一种实现方式
。
协议直白来讲是一种约定,rpc和http都是为了服务器间的通信而生,都需要制定一套标准协议来进行通信。不过HTTP比较火,是一个全世界的统一约定,使用比较广泛。但通用也意味着冗余,所以后来又产生了很多RPC框架(自定义协议,具备优秀的性能等)
我们可以自定义RPC请求/响应 包含的消息头和消息体结构,自定义编解码方式,自定义网络通信方式,只要
client
和
server
消息的发送和解析能对应即可,这些问题确认下来,一个RPC框架就设计出来了
。
下面先从请求过程看一下RPC和HTTP都会经历哪些阶段,然后再分阶段去做对比
一次请求的过程
从请求链路可以看到,最核心的只有三层:编解码、协议、网络通信
下面会从这3个角度去对比HTTP和RPC
HTTP VS RPC自定义协议
HTTP和RPC 2个关键词不具备可比较性,因为RPC包含了HTTP。
但是RPC自定义协议(thrift, protobuf, dubbo, kitex-thrift等) 是RPC的具体实现,HTTP也是RPC的具体实现,它们是具备可比较性的
编解码(序列化)
- 序列化: 指将程序运行过程中的动态内存数据(java的class、go的struct)转化为硬盘中静态二进制数据的过程,以方便网络传输。
- 反序列化:指将硬盘中静态二进制数据转化为程序运行过程中的动态内存数据的过程,以方便程序计算。
HTTP/1.1 一般用json
自定义RPC协议 一般用 thrift、protobuf
协议层
编码之后,数据转换成字节流,但是RPC通信时,每次请求发送的数据大小不是固定的,那么为了区分消息的边界,避免粘包、半包等现象,我们需要定义一种协议,来使得接收方能够正确地读出不定长的内容。简单点说,通信协议就是约定客户端和服务器端传输什么数据,以及如何解析数据。
可参考
1、kitex:概览,传输协议
2、dubbo:triple 协议,概览
可以思考一下 序列化、传输协议、网络通信的关系,下面以kitex为例进行分析
kitex codec 接口定义,kitex thrift 序列化实现,kitex ttheader协议,kitex 发送请求核心代码
可以发现 Encode中,先根据message构造出header,写入out,然后再把data(实际的业务数据)写到out。
encode函数完全遵守 ttheader协议去构造数据。
最后再把out通过网络库发送出去
网络通信层
网络通信层主要提供一个易用的网络库,封装了操作系统提供的socket api。HTTP的长连接和TCP长连接不是一个东西,需要注意下,TCP Keepalive是操作系统实现的功能,并不是TCP协议的一部分,需要在操作系统下进行相关配置(只能保证网络没问题,不能代表服务没问题)
其中 HTTP2 拥有多路复用、优先级控制、头部压缩等优势
可以参考
kitex:连接类型
RPC自定义协议 和 HTTP的使用场景
公司内部的微服务,对客户端提供的服务 适合用RPC,更好的性能
对外服务、单体服务、为前端提供的服务适合用HTTP
我的思考
rpc在编解码、协议层、网络通信 都比HTTP有更大的优势,那为啥不把HTTP换成RPC呢
1、人的认知,HTTP已经深入人心(或者说生态好,通用性强),几乎所有的机器、浏览器和语言默认都会支持。但是自定义RPC协议 可能很多人都没听过(比如kitex、dubbo等),还让别人支持,根本不可能。
- 需要建设全局的DNS等等,HTTP链路中的组件都需要换成 自定义的那一套,成本极高。
但是公司内部可以搞成一套,可以极大提高性能,何乐而不为。
我见过的案例是很多时候并没有深入思考为什么用,而是大家都这么用,我也这么用。
举例:protobuf不支持前端语言,但是支持java
就是自定义编解码框架支持语言有限,很多语言没有工具可以做,并且浏览器也不支持。对于问题排查比较困难。
https://github.com/protocolbuffers/protobuf#protobuf-runtime-installation
公司内部实际案例:服务端和客户端交互时,为了提高性能,采用protobuf编解码数据,使用http协议传输数据。
但是每次请求/响应数据都是不可读的。服务端会把protobuf编码前的数据转为json,用于打印log/存储,方便排查问题。
我理解是协议层用的http,但是内部的运行机制还是自定义的。http只是定义了传输数据的格式。举个例子:http的流量控制其实用的是 tcp的滑动窗口,http协议本身不具备这些功能。但是rpc是可以自己加这些功能的。这些功能必然有数据传输,这个传输协议用的http。
作者:cli
链接:https://juejin.cn/post/7264454873588449336
来源:稀土掘金