RPC基础
- 概念:远程服务调用,是通过网络请求远程计算机程序服务的通信技术。RPC框架封装好了底层网络通信、序列化等技术,我们只需要在项目中引入各个服务的接口包,就可以实现在代码中调用RPC服务同调用本地方法一样。正因为这种方便、透明的远程调用,RPC被广泛应用与当下企业级以及互联网项目中,是实现分布式系统的核心。
- 种类:springcloud Feigh、gRPC、thrift、RMI、dubbo、HadoopRPC。
- 核心(重点围绕):通信协议 和 序列化(xml、json、protobuf、thrift)。
- 原理:Client(调用) --> ClientStub(序列化) 《==(网络传输)==》 ServerStub(反序列化)--> Server(处理)
RPC核心
- 在于通信协议和序列化
协议
- 远程调用需要先定义协议,这样才能解析正确信息
常见的三种协议形式:
- 固定长度形式
- 特殊服务隔断形式
- header + body 形式
固定长度形式
- 指的是协议的长度是固定的
- 好处:效率高、无脑读一定长度就解析
- 坏处:长度固定,短了需要填充
特殊字符隔断形式
- 定义一个特殊结束符,根据特殊的结束符来判断一个协议单元的结束,比如用换行符等等
- 好处:长度自由,用特殊字符截断
- 坏处:需要一直读取直到一个完整的协议单元之后才能开始解析,同时如果混入这个特殊字符就会出错
header 和 body 形式
- header 固定长度,会填写body的长度;body 不固定长度,使得伸缩性比较好
- dubbo 协议就是属于 header 和 body 形式,同时具有特殊字符 0xdabb
- dubbo 协议头部: 16字节主要携带了请求设置、消息体长度、魔法数(就是特殊字符 0xdabb,用来解决 TCP 粘包问题)等待
- dubbo 协议体:包括协议版本、接口名称、接口版本、方法名字等等
- TCP粘包
序列化
- 网络是以字节流的形式传输的,所以需要将对象压缩成字节流来进行远程传输
- Dubbo 默认用的是 hessian2 序列化协议
常见的序列化形式:
- 字符型(XML、JSON)
- 二进制流(HTTP2.0、Thrift)
字符型
- 代表就是 XML、JSON
- 好处:调试方便、可以直观的知道哪个字段对应的哪个参数
- 坏处:传输效率低、有很多冗余的定西,比如:JSON 的括号等
二进制流
- 代表就是 HTTP2.0、Thrift
- 好处:传输效率高、对机器更友好、数据更加紧凑
- 坏处:调试困难
RPC框架
RPC常见问题
RPC与HTTP的区别?
- RPC远程过程调用,是对不同应用间相互调用的一种描述,侧重点在于应用间服务的调用,实现包括处理调用语义(函数名,参数,返回值,异常,序列化等);主要使用在公司内部的服务调用,性能消耗低,传输效率高,服务治理方便;
- HTTP是一种应用层网络传输协议,侧重点在于网络数据包可靠高效地传输;主要用于对外的异构环境,浏览器接口调用,APP接口调用,第三方接口调用;
- RPC调用的数据传输可以基于HTTP协议、TCP协议、UDP协议,数据传输只是RPC的一部分,还有处理调用的语义等;
- 参考 HTTP2.0
传输协议
- RPC:可以基于TCP协议,也可以基于HTTP协议;
- HTTP:基于HTTP协议。
传输效率
- RPC:使用自定义的TCP协议,可以让请求报文体积更小,或者使用HTTP2协议,也可以很好的减少报文体积,提高传输效率;
- HTTP:使用HTTP1.1协议,请求中会包含很多无用的内容
性能消耗(序列化)
- RPC:可以基于thrift实现高效的二进制传输;
- HTTP:大部分使用Json来实现的,字节大小和序列化耗时更高。
RPC独有
- 负载均衡
- 服务治理
如何自己实现一个 RPC 框架
- 注册中心:注册中心负责服务地址的注册与查找,相当于服务目录
- 网络传输:既然我们要调用远程的方法,就要发送网络请求来传递 目标类、方法信息、方法参数等数据到服务提供端
- 序列化和反序列化:要在网络传输数据就要涉及到序列化
- 动态代理:屏蔽方法调用的底层细节
- 负载均衡:避免单一服务器响应同一请求,容易造成服务器宕机、崩溃等问题
- 传输协议:这个协议是客户端和服务端交流的基础
- 监控模块
- 如何自己实现一个RPC框架?