在这一部分,我学习了RPC 相关的基本概念、RPC 框架的分层设计、衡量 RPC 框架的一些核心指标以及对字节内部 RPC 框架 Kitex 有所了解,相对于上一篇,这一篇侧重于对字节内部 RPC 框架 Kitex的学习,以及对rpc新趋势的了解。最后,对课后问题进行了解答。
RPC 的基本概念
RPC(Remote Procedure Call)是一种远程过程调用的通信协议,允许一个程序调用另一个程序或进程中的函数或方法,就像调用本地函数一样,而无需显式地处理网络通信细节。
在分布式系统中,不同的计算机或进程之间需要进行通信以协同完成任务。RPC提供了一种方便的方式来实现远程通信,能够像调用本地函数一样调用远程函数,而不必担心底层的网络通信细节。
RPC的概念模型
涉及了客户端(User)、客户端代理(User-Stub)、运行时库(RPC-Runtime)、服务器端代理(Server-Stub)以及服务器端(Server) 等角色和组件,它们协同工作以实现远程过程调用的功能。通过这种方式,可以像调用本地函数一样调用远程服务器上的函数,而不必关心底层的网络通信细节。
工作流程
RPC的工作流程包括客户端调用、数据传输、服务端处理和结果返回等步骤。客户端将函数调用和参数封装成请求,通过网络发送给服务端。服务端接收到请求后,解析请求并执行对应的函数,将结果封装成响应返回给客户端。整个过程需要处理网络通信、序列化、反序列化、错误处理等多个环节。
RPC协议的设计与实现
常见的RPC框架如gRPC、Dubbo、Thrift等都实现了类似的RPC协议。这些框架设计了通信协议、序列化方式、负载均衡等核心组件,以支持跨网络的远程调用。它们的设计思想强调性能、可扩展性和易用性,可以根据应用需求选择合适的框架。
序列化和反序列化
在RPC中,数据需要在网络上进行传输,而不同机器上的程序使用的数据结构可能不同。因此,需要将数据进行序列化(将数据转换成字节流)和反序列化(将字节流转换成数据)操作。常见的序列化方式有JSON、Protobuf、Avro等,每种方式都有其优缺点,选择合适的方式取决于性能、数据大小和复杂度等因素。
RPC 框架核心指标
稳定性
-
保障策略
- 熔断
- 限流
- 超时控制
从某种程度上讲超时、限流和熔断也是一种服务降级的手段 。
-
请求成功率
- 负载均衡
- 重试
-
长尾请求
- BackupRequest
易用性
-
开箱即用
- 合理的默认参数选项、丰富的文档
-
周边工具
- 生成代码工具、脚手架工具
扩展性
- Middleware:middleware 会被构造成一个有序调用链逐个执行,比如服务发现、路由、负载均衡、超时控制等
- Option:作为初始化参数
- 核心层是支持扩展的:编解码、协议、网络传输层
- 代码生成工具也支持插件扩展
观测性
-
三件套:Log、Metric 和 Tracing
-
内置观测性服务,用于观察框架内部状态
- 当前环境变量
- 配置参数
- 缓存信息
- 内置 pprof 服务用于排查问题
高性能
- 连接池和多路复用:复用连接,减少频繁建联带来的开销
- 高性能编解码协议:Thrift、Protobuf、Flatbuffer 和 Cap'n Proto 等
-
高性能网络库:Netpoll 和 Netty 等