RPC 原理与实践| 青训营笔记

105 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天

RPC(Remote Procedure Call)即远程过程调用,是一种计算机通信协议,它允许一个进程(称为客户端)通过网络调用另一个进程(称为服务器)的一个服务而不需要了解底层网络细节。RPC 协议在分布式系统中发挥了重要作用。本文将简要介绍 RPC 的原理及实践。

一、RPC 原理

RPC 的主要原理是让远程服务的调用看起来像本地服务的调用,使得分布式系统间的调用过程更加简单、直观、快速。具体来说,RPC 协议的实现流程如下:

  1. 客户端通过调用本地 Stub(桩)代理对象的接口方法,传入参数。
  2. Stub 对象将参数序列化,并组装成合适的 RPC 请求格式。
  3. 请求数据通过网络传输到服务端。
  4. 服务端接收到请求数据后,通过解析数据,得到请求信息,并将请求信息反序列化为方法参数。
  5. 服务端调用本地服务方法,处理请求,并返回结果。
  6. 返回结果被序列化为响应数据,并通过网络传输到客户端。
  7. 客户端接收到响应数据后,通过解析数据,得到返回值。

通过 RPC 协议,客户端与服务端之间的通信可以像本地调用一样,无需了解底层通信细节。

二、 RPC实现

RPC实现方式有很多,常见的有两种:基于HTTP协议的RESTful API和基于二进制协议的远程调用。

基于HTTP协议的RESTful API是一种比较简单易用的RPC实现方式,通过HTTP协议传输数据,基于RESTful API的RPC实现可以使用各种编程语言和框架,比较灵活。在实际使用中,RESTful API主要用于提供数据接口和构建微服务架构,但其性能和效率相对较低,不适合处理大量的请求和响应。

而基于二进制协议的远程调用则是一种高效的RPC实现方式。通过使用二进制协议,可以将数据传输和解析的开销降到最低,大幅提高RPC的性能和效率。常用的二进制协议有Thrift、Protobuf等,这些协议具有高效的数据传输和解析机制,能够很好地支持分布式系统的构建。

RPC框架的分层设计:

image.png

此外,RPC实现过程中还需要考虑安全性和可靠性。安全性主要是指在传输过程中数据不被恶意攻击者窃取或篡改,而可靠性主要是指系统在遭遇各种异常情况时能够保证正常运行。

三、RPC 实践

RPC 协议广泛应用于分布式系统中,尤其是微服务架构中。下面简要介绍 RPC 实践中的一些关键技术。

  1. 序列化协议

序列化协议是 RPC 实现中的重要组成部分,它用于将对象序列化为字节数组,或将字节数组反序列化为对象。常见的序列化协议有 Java 中的 Java Serialization、JSON、XML、Thrift、Protocol Buffers 等。在选择序列化协议时,需要根据系统的性能需求、语言特性、序列化效率、序列化大小等因素进行权衡。

  1. 通信协议

通信协议是 RPC 实现中的另一个关键组成部分,它用于定义 RPC 消息的格式、传输方式等。常见的通信协议有 HTTP、TCP、UDP 等。在选择通信协议时,需要考虑系统的实时性、可靠性、传输效率等因素。

  1. 注册中心

在分布式系统中,需要实现服务发现和注册,以便客户端可以找到可用的服务提供者。注册中心是实现服务发现和注册的关键技术之一,它记录了当前可用的服务提供者和其 IP 地址等信息,客户端可以通过查询注册中心来获取可用服务。

字节内部 Kitex 实践分享

  1. 框架文档 Kitex
  1. 自研网络库 Netpoll,背景:

    a. 原生库无法感知连接状态
    b. 原生库存在 goroutine 暴涨的风险

  1. 扩展性:支持多协议,也支持灵活的自定义协议扩展
  1. 性能优化,参考 字节跳动 Go RPC 框架 KiteX 性能优化实践

    a. 网络优化

    • i. 调度优化
    • ii. LinkBuffer 减少内存拷贝,从而减少 GC
    • iii. 引入内存池和对象池

    b. 编解码优化

    • i. Codegen:预计算提前分配内存,inline,SIMD等
    • ii. JIT:无生产代码,将编译过程移到了程序的加载(或首次解析)阶段,可以一次性编译生成对应的 codec 并高效执行
  1. 合并部署

    a. 微服务过微,引入的额外的传输和序列化开销越来越大
    b. 将强依赖的服务统计部署,有效减少资源消耗