基本概念
RPC需要解决的问题有:函数映射、数据转换成字节流、网络传输。
RPC概念模型:1984年Nelson发表了论文《implementing Remote Procedure Calls》,其中提出了RPC的过程由5个模型组成:User、User-Stub、RPC-Runtime、Server-Stub、Server。
IDL(Interface Description Language)文件:IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信。
生成代码:通过编译器工具把IDL文件转换成语言对应的静态库。
编解码:从内存中表示到字节序列的转换称为编码,反之为解码,也常叫做序列化和反序列化。
通信协议:规范了数据在网络中的传输内容和格式。除必须的请求/响应数据外,通常还会包括额外的元数据。
网络传输:通常基于成熟的网络库走TCP/UDP传输。
RPC的好处:
- 单一职责,有利于分工协作和运维开发。
- 可扩展性强,资源使用率更高。
- 故障隔离,服务的整体可靠性更高
PRC的问题:
- 服务宕机,对方应该如何处理。
- 在调用过程中网络发送异常,如何保证消息的可达性。
- 请求量突增导致服务无法及时处理,有哪些应对措施。
分层设计
Apache Thrift:
Client Server
------------------ ---------------------
| Code | | Code |
------------------ ---------------------
| Service.client | | Service.Processor | -> 通过代码生成工具把IDL文件
------------------ --------------------- -> 转换称不同语言对应的lib代码,
| read/write | | read/write | -> 里面封装了编解码逻辑
------------------ ---------------------
| TProtocal | | TProtocal | -> 框架的编解码层
------------------ ---------------------
| TTransport | | TTransport | -> 框架的协议层
------------------ ---------------------
| . | | . |
| . | | . |
| . | | . |
------------------ ---------------------
| Network IO | <-------------> | Network IO |
------------------ ---------------------
编解码层
据格式
语言特点的格式:许多编程语言都内建了将内存对象编码为字节序列的支持,例如 Java 有 java.io.Serializable。
文本格式:JSON、XML、CSV 等文本格式,具有人类可读性。
二进制编码:具备跨语言和高性能等优点,常见有Thrift的BinaryProtocol,Protobuf等。
选型
兼容性:支持自动增加新的字段,而不影响老的服务,这将提高系统的灵活度。
通用性:支持跨平台、跨语言。
性能:从空间和时间两个维度来考虑,也就是编码后数据大小和编码耗费时长。
关键指标
稳定性:
- 熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路。
- 限流:保护被调用方,防止大流量把服务压垮。
- 超时控制:避免浪费资源在不可用节点上。 框架通过中间件来注册各种服务治理策略,保障服务的稳定性。
易用性:
- 开箱即用:合理的默认参数选项、丰富的文档。
- 周边工具:生成代码工具、脚手架工具。
通过提供合理的默认配置和方便的命令行工具可以提升框架的易用性。
扩展性:Middleware、Option、编解码层、协议层、网络传输层、代码生成工具插件扩展。框架应当提供丰富的扩展点,例如核心的传输层和协议层。
观测性:Log、Metric、Tracing、内置观测性服务。观测性除了传统的Log、Metric和Tracing之外,内置状态暴露服务也很有必要
高性能,生能可以从多个层面去优化,例如选择高性能的编解码协议和网络库。
总结
Remote Procedure Call (RPC) 是一种通信模式,旨在让不同的计算机程序在网络上像调用本地函数一样进行通信。为了实现有效的远程调用,RPC需要解决函数映射、数据序列化、网络传输等问题。
RPC的概念模型由五个组成部分构成:用户(User)、用户存根(User-Stub)、RPC运行时(RPC-Runtime)、服务器存根(Server-Stub)和服务器(Server)。IDL(Interface Description Language)文件通过中立的方式描述接口,使得不同平台和不同编程语言的程序能够相互通信。生成代码将IDL文件编译成相应语言的静态库,编解码将数据转换为字节序列进行传输,通信协议规范了数据传输的内容和格式,网络传输基于成熟的网络库走TCP/UDP。
RPC的好处包括单一职责、可扩展性、故障隔离等,但也面临服务宕机、网络异常和高并发等问题。
分层设计在RPC中起着重要作用,例如Apache Thrift采用了客户端、客户端存根、RPC运行时、服务器存根和服务器的层次结构。编解码层决定了数据在网络中的传输格式,根据语言特点和需求可选择不同的数据格式,如文本格式或二进制编码。
在选择RPC框架时,需考虑兼容性、通用性、性能和易用性等因素。稳定性通过熔断、限流和超时控制来保障。易用性涉及框架的默认配置和工具。扩展性涉及各个层次的插件扩展。观测性包括日志、指标、追踪等。高性能则涉及编解码协议和网络库的选择和优化。
RPC作为一种通信模式,通过解决编解码、网络传输等问题,使得不同程序可以在网络上进行远程调用,通过合适的框架选择和设计,可以实现高效、稳定和易用的远程通信。