深入浅出 RPC 框架

RPC 框架分层设计

基本概念

RPC (Remote procedure call 远程函数调用)是一种通过网络调用远程服务的方法,使程序可以像调用本地函数一样调用分布式系统中位于远程服务器上的函数。

函数映射数据转换成字节流网络传输

函数映射

在客户端调用一个远程函数时,如何将该调用正确映射到服务端对应的函数

服务注册,函数唯一标识符id,接口定义语言(IDL)

本地和远程是不同的进程,不共享内存

数据转换成字节流

将函数的参数和返回值序列化为可以通过网络传输的字节流格式

序列化(Serialization):将参数和返回值转换为字节流。

  • 常用格式:JSON、XML(文本格式,易读但较慢);Protocol Buffers、Thrift、Avro(二进制格式,高效但不易读)。

反序列化(Deserialization):将接收到的字节流还原为原始数据。

序列化工具:

  • JSON:简单易用,语言无关,但性能不高。
  • Protocol Buffers(Protobuf):高效二进制序列化,适合高性能 RPC。
  • Thrift:序列化与 RPC 框架结合,支持多语言。

网络传输

负责将序列化后的字节流在客户端与服务端之间传输

IDL—平台之间通信的统一规范接口

IDL(Interface description language)

一种描述接口(包括方法和数据结构)的语言,用于定义客户端与服务端之间的通信协议。它抽象出服务的接口定义,并支持跨语言的实现,使客户端和服务端能够通过生成代码来实现一致的交互

IDL声明自己的方法,参数,按照约定调用

双方共用一套IDL,可以利用工具生成代码

微服务

一种软件架构风格,它将一个大型的应用程序拆分为多个独立的、松耦合的服务,每个服务专注于实现单一业务功能。微服务架构的核心思想是将应用程序划分为独立运行的小服务,这些服务可以单独开发、部署和扩展

好处

单一职责,分工协作,便于运维开发

可扩展性强、灵活性、故障隔离

弊端

网络消息可达性、开发复杂度增加、运维成本高

分层设计

RPC框架

微服务的问题将由RPC框架解决,通过框架的工具化和标准化减少了开发和运维中的复杂度

网络通信层、协议层、编解码层

编解码层

负责将数据转换为适合网络传输的格式(序列化)以及从网络数据中恢复原始数据(反序列化)

生成代码,同一份IDL文件生成对应不同语言的版本

数据格式:语言特定的格式、文本格式、二进制编码

语言特定的格式:编程语言内建支持将内存对象编码为字节序列

文本格式:JSON、XML、CSV,人类可读

二进制编码:跨语言,高性能 Thrift、Protobuf

编码格式的选型(需要考量的因素)

兼容性、通用性、性能

兼容性:自动增加新的字段,不影响老的服务

通用性:跨平台跨语言

性能:空间(编码后数据大小)、时间(编码时长)

协议层

定义客户端与服务端之间数据传输的规则,解决如何区分和解析协议单元的问题

如何区分各个协议单元:特殊结束符变长协议

特殊结束符:特殊字符表示结束

​ HTTP协议头是以 回车+换行 结束

变长协议:定长+不定长,定长描述不定长长度

​ header+body

协议解析

网络通信层

底层负责数据的传输,通常使用操作系统提供的 Sockets API 直接管理网络通信

负责在客户端与服务端之间建立连接、发送数据包、接收响应

创建 socket 对象(支持 TCP/UDP 协议),绑定地址和端口,监听、发送和接收数据。

网络库

在 Sockets API 基础上进一步封装,提供易用性、功能性和性能优化的网络通信功能

提供易用API、功能、性能

关键指标分析与企业实践

关键指标

稳定性、易用性、扩展性、观测性、高性能

稳定性

熔断、限流、超时控制

请求成功率:负载均衡、重试

长尾请求:备份请求

实际解决-注册中间件

易用性

开箱即用、周边工具

开箱即用:合理的默认参数、丰富的文档

周边工具:生成代码工具、脚手架工具

扩展性

Middleware、Option、编解码层、协议层、网络传输层、代码生成工具插件扩展

观测性

传统三件套:Log、Metric、Tracing

Log日志

Metric监控:监控面板

Tracing链路跟踪:层层请求的耗时,通过一个id把一层层串起来

高性能

高吞吐低延迟

企业实践

Kitex

自研网络库

原生库连接池中存在失效连接,存在goroutine暴涨的风险

合并部署:将亲和性强的服务实例调度到同一个物理机,远程RPC调用优化为本地IPC调用