文章目录
- RPC 的通信流程
- 02 | 协议:怎么设计可扩展且向后兼容的协议?
- 03 | 序列化:对象怎么在网络中传输?
- 04 | 网络通信:RPC框架在网络通信上更倾向于哪种网络IO模型?
- 05 | 动态代理:面向接口编程,屏蔽RPC处理流程
- 08 | 服务发现:到底是要 CP 还是 AP?
- 09 | 健康检测:这个节点都挂了,为啥还要疯狂发请求?
- 10 | 路由策略:怎么让请求按照设定的规则发到不同的节点上?
- 11 | 负载均衡:节点负载差距这么大,为什么收到的流量还一样?
- 12 | 异常重试:在约定时间内安全可靠地重试
- 13 | 优雅关闭:如何避免服务停机带来的业务损失?
- 14 | 优雅启动:如何避免流量打到没有启动完成的节点?
- 15 | 熔断限流:业务如何实现自我保护?
- 16 | 业务分组:如何隔离流量?
RPC 的通信流程
帮助我们屏蔽网络编程细节,实现调用远程方法就跟调用本地(同一个项目中的方法)一样的体验,我们不需要因为这个方法是远程调用就需要编写很多与业务无关的代码。

- 调用方将数据 进行序列化,并 根据 约定的协议 进行编码。
- 网络传输
- 根据 约定的协议 进行解码,反序列化出对象。
- 提供方再根据反序列化出来的请求对象找到对应的实现类,完成真正的方法调用,然后把执行结果序列化后,回写到对应的 TCP 通道里面。调用方获取到应答的数据包后,再反序列化成应答对象,这样调用方就完成了一次 RPC 调用
02 | 协议:怎么设计可扩展且向后兼容的协议?
- 为什么不直接使用 Http 协议?
- A:请求头中的其他信息太多,比如 \r \n,http 版本信息等等。
一般 的设计就是这样:

03 | 序列化:对象怎么在网络中传输?
JDK 的序列化过程是怎样完成的呢?我们看下下面这张图:

序列化过程就是在读取对象数据的时候,不断加入一些特殊分隔符,这些特殊分隔符用于在反序列化过程中截断用。
- 头部数据用来声明序列化协议、序列化版本,用于高低版本向后兼容
- 对象数据主要包括类名、签名、属性名、属性类型及属性值,当然还有开头结尾等数据,除了属性值属于真正的对象值,其他都是为了反序列化用的元数据
- 存在对象引用、继承的情况下,就是递归遍历“写对象”逻辑
实际上任何一种序列化框架,核心思想就是设计一种序列化协议,将对象的类型、属性类型、属性值一一按照固定的格式写到二进制字节流中来完成序列化,再按照固定的格式一一读出对象的类型、属性类型、属性值,通过这些信息重新创建出一个新的对象,来完成反序列化。
JSON 的序列化方式
JSON 是典型的 Key-Value 方式,没有数据类型,是一种文本型序列化框架
缺点:
-
JSON 进行序列化的额外空间开销比较大,对于大数据量服务这意味着需要巨大的内存和磁盘开销;
-
JSON 没有类型,但像 Java 这种强类型语言,需要通过反射统一解决,所以性能不会太好。
-
Hessian:动态类型、二进制、紧凑的,并且可跨语言移植的一种序列化框架。Hessian 协议要比 JDK、JSON 更加紧凑,性能上要比 JDK、JSON 序列化高效很多,而且生成的字节数也更小。
-
Protobuf:Protobuf 是 Google 公司内部的混合语言数据标准,是一种轻便、高效的结构化数据存储格式,可以用于结构化数据序列化,支持 Java、Python、C++、Go 等语言。Protobuf 使用的时候需要定义 IDL(Interface description language),然后使用不同语言的 IDL 编译器,生成序列化工具类,它的优点是:
- 序列化后体积相比 JSON、Hessian 小很多
- IDL 能清晰地描述语义,所以足以帮助并保证应用程序之间的类型不会丢失,无需类似 XML 解析器
- 序列化反序列化速度很快,不需要通过反射获取类型
- 消息格式升级和兼容性不错,可以做到向后兼容
RPC 框架中如何选择序列化?


本文深入探讨了RPC框架的核心技术,包括通信流程、协议设计、序列化选择、网络IO模型、动态代理、服务发现、健康检测、路由策略、负载均衡、异常重试、优雅启停、熔断限流和业务分组等内容。
最低0.47元/天 解锁文章
433

被折叠的 条评论
为什么被折叠?



