深入浅出RPC框架|青训营笔记

90 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第5篇笔记。

一、基本概念

RPC(Remote Procedure Call,远程过程调用)是一种计算机通信协议,允许调用不同进程空间的程序。RPC 的客户端和服务器可以在一台机器上,也可以在不同的机器上。程序员使用时,就像调用本地程序一样,无需关注内部的实现细节。

  1. 远程函数调用(RPC -Remote Procedure Calls)

    • 函数映射
    • 数据转换成字节流
    • 网络传输
  2. RPC完整过程

    1. IDL文件(如Thrift,Protobuf):

      通过中立的方式描述接口,使不同平台上运行的对象和用不同语言编写的程序可以相互通信

    2. 生成代码:

      通过相应的编译工具把IDL文件转换成语言对应的静态库

    3. 编解码:

      从内存中表示转换到字节序列称为编码,反之为解码,也可以叫做序列化和反序列化。

    4. 通信协议:

      规范数据在网络中的传输内容和格式。除了必需的请求/响应数据外,通常包含额外的元数据。

    5. 网络传输:

      通常基于成熟的TCP/UDP传输

  3. RPC优点

    • 单一职责,有利于分工协作和运维开发
    • 可扩展性强,资源使用率更优
    • 故障隔离,服务的整体可靠性更高
  4. RPC缺点(RPC框架处理)

    • 被调用服务宕机,调用方怎么处理
    • 调用过程中发生网络异常,如何保证消息可达
    • 请求量突增导致服务无法及时处理

二、分层设计

  1. 编解码层

    • 数据格式

      • 语言特定格式

        如Java的java.io.Serializable

      • 文本格式

        JSON、XML、CSV等,可读性强

      • 二进制编码

        跨语言、高性能。如Protobuf和Thrift的BinaryProtocol

    • 二进制编码

      • TLV编码(Tag、Lenght是额外开销):

        Tag:标签/类型

        Lenght:长度

        Value:值,可嵌套TLV

    • 选型

      • 兼容性

        支持自动增加新的字段,而不影响旧服务

      • 通用性

        支持跨平台和语言

      • 性能

        编码后数据大小和编码耗费时间

  2. 协议层

    • 概念:

      • 特殊结束符

        一个特殊字符作为每个协议单元结束的标示

      • 变长协议:

        以定长加不定长的部分组成,其中定长的部分需要描述不定长的内容长度

    • 协议构造:(Apache Thrift为例)

      • LENGTH:数据包大小,不包括本身
      • HEADER MAGIC:标识版本信息
      • SEQUENCE NUMBER:表示数据包seqID,用于多路复用,但连接内递增
      • HEADER SIXE:头部长度,从第14个字节计算到PAYLOAD前
      • PROTOCOL ID:编解码方式
      • TRANSFORM ID:压缩方式
      • INFO ID:传递定制meta信息
      • PAYLOAD:消息体
    • 协议解析

  3. 网络通信层

    • Sockets API

    • 网络库:

      • 提供简单易用API:

        • 封装底层Socket API
        • 连接管理和事件分发
      • 功能:

        • 协议支持:tcp、udp和uds等
        • 优雅退出、异常处理等
      • 性能:

        • 应用层buffer减少copy
        • 高性能定时器、对象池等

三、关键指标

  • 稳定性:

    • 保障策略:

      • 熔断:

        保护调用方,防止被调用的服务出现问题而影响整个链路

      • 限流:

        保护被调用方,防止大流量压垮服务

      • 超时控制:

        避免浪费资源在不可用节点上

    • 请求成功率:

      • 负载均衡
      • 重试
    • 长尾请求(明显高于平均响应时间的小部分请求):

      备份请求

    • 注册中间件:

  • 易用性:

    • 开箱即用:

      • 提供合理的默认参数
      • 文档丰富
    • 周边工具:

      • 生成代码工具、脚手架工具
  • 扩展性:

    • 中间件
    • 参数
    • 编解码层
    • 协议层
    • 网络协议层
    • 代码生成工具插件扩展
  • 观测性:

    • Log、Metric、Tracing
    • 内置观测性服务
  • 高性能:

    • 场景:

      • 单机多机
      • 但连接多连接
      • 单/多client 单/多server
      • 不同大小的请求包
      • 不同请求类型
    • 目标:

      • 高吞吐
      • 低延迟
    • 手段:

      • 连接池
      • 多路复用
      • 高性能编解码协议
      • 高性能网络库

四、RPC与基于HTTP的Restful API对比

  • Restful API 有相对统一的标准,因而更通用,兼容性更好,支持不同的语言。HTTP 协议是基于文本的,一般具备更好的可读性。
  • Restful 接口需要额外的定义,无论是客户端还是服务端,都需要额外的代码来处理,而 RPC 调用则更接近于直接调用。
  • 基于 HTTP 协议的 Restful 报文冗余,承载了过多的无效信息,而 RPC 通常使用自定义的协议格式,减少冗余报文。
  • RPC 可以采用更高效的序列化协议,将文本转为二进制传输,获得更高的性能。
  • 因为 RPC 的灵活性,所以更容易扩展和集成诸如注册中心、负载均衡等功能。