RPC框架 | 青训营笔记

80 阅读3分钟

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

RPC框架初探

  • RPC调用需要解决的问题

    • 函数映射
    • 数据转换成字节流
    • 网络传输
  • RPC概念模型

image-20230210104738699

  • RPC调用过程

image-20230210105007077

  • RPC的好处

    • 单一职责,有利于分工协作和运维开发
    • 可扩展性强,资源使用率更优
    • 故障隔离,服务的整体可靠性更高
  • RPC面临的挑战

    • 服务宕机,对方应该如何处理?
    • 在调用过程中发生网络异常,如何保证消息的可达性?
    • 请求量突增导致服务无法及时处理,有哪些应对措施?
  • RPC框架结构

image-20230210105410374

  • 编解码层传递的数据形式

    • 语言特定的格式

      • 许多编程语言都内建了将内存对象编码为字节序列的支持,例如 Java 有 java.io.Serializable
      • 方便但是不利于兼容性,导致语言和功能高度绑定,并且也不利于安全设计
    • 文本格式

      • JSON、XML、CSV 等文本格式,具有人类可读性
      • 便于人类理解,但是由于数字的编码存在歧义,比如XML和CSV不能区分数字和字符串,JSON虽然区分字符串但是不区分整数和浮点数,而且json的序列化和反序列化有时还需要依赖反射,性能较差
    • 二进制编码

      • 具备跨语言和高性能等优点,常见有 Thrift 的 BinaryProtocol,Protobuf 等
      • TLV编码和Varint编码
  • TLV编码形式(扩展性好,但是有type和length两个冗余字段)

image-20230210110017975

  • 编码选择的考量

    • 兼容性:支持自动增加新的字段,而不影响老的服务,这将提高系统的灵活度
    • 通用性:支持跨平台、跨语言
    • 性能:从空间和时间两个维度来考虑,也就是编码后数据大小和编码耗费时长
  • 协议层数据包以及对应结构

image-20230210110313948

image-20230210110324833

  • 网络通信层相关

image-20230210110519272

  • 往往使用网络库来代替复杂的socket编程,以下是网络库选择的考量

    • 提供易用 API:封装底层 Socket API连接管理和事件分发
    • 功能:协议支持: tcp、udp 和 uds 等优雅退出、异常处理等
    • 性能:应用层 buffer 减少 copy,高性能定时器、对象池等

RPC框架的性能指标

  • 常用指标:稳定性,易用性,扩展性,观测性,高性能

  • 稳定性相关

    • 长尾请求:往往是指调度时间明显高于均值的请求,业界关于延迟有一个常用的P99标准,认为末端的1%就可以视为长尾请求,在复杂的系统中长尾请求是不可避免的,可能是由于网络抖动,GC,系统调度等原因(往往使用超时重试解决)

image-20230210110911139

image-20230210110919643

image-20230210111002919

  • 易用性相关

    • 开箱即用:合理的默认参数选项、丰富的文档
    • 周边工具:生成代码工具、脚手架工具
  • 扩展性相关

    • 一次请求发起会先经过治理层面,治理的逻辑封装在中间件中,通过链式调用来自由调度

image-20230210111553141

  • 观测性相关

    • Log、Metric、 Tracing,常见基本三件套
    • 内置观测性服务(往往使用一个简单的HTTP请求解决)
  • 高性能相关

image-20230210111931271

字节自研Kitex

  • 整体架构

image-20230210112134625