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

109 阅读3分钟

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

本文是对深入浅出 RPC 框架课程主要内容的整理

基本概念

  • 相比本地函数调用,RPC调用需要解决的问题

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

    • RPC过程由5个模型组成:User、User-Stub、RPC-Runtime、Server-Stub、Server

    image-20220524121121833.png

    image-20220524121356234.png

  • RPC的好处

    • 单一职责,开发、部署以及运维都是独立的
    • 可扩展性强,压力过大时可以独立扩展资源,底层基础服务可以复用,节省资源
    • 某个模块发生故障,不会影响整体的可靠性
  • RPC 带来的问题将由 RPC 框架来解决

    • 服务宕机如何感知?
    • 遇到网络异常应该如何应对?
    • 请求量暴增怎么处理?

RPC 框架分层设计

  • 以Apache Thrift为例

    image-20220524121935835.png

编解码层

  • 数据格式

    • 语言特定格式:例如 java.io.Serializable,好处是非常方便,可以用很少的额外代码实现内存对象的保存与恢复。但是这类编码通常与特定的编程语言深度绑定,其他语言很难读取这种数据。此外还有安全性和兼容性的问题。
    • 文本格式:例如 JSON、XML、CSV 等,优点在于可读性强,但数字编码多有歧义之处,如XML和CSV不能区分数字和字符串;JSON不能区分整数和浮点数,且不能指定精度。JSON在一些语言中的序列化和反序列化需要采用反射机制,所以性能也比较差。
    • 二进制编码:常见有 Thrift 的 BinaryProtocol,Protobuf,实现可以有多种形式,例如 TLV 编码 和 Varint 编码

RPC 框架核心指标

稳定性

框架通过中间件来注入各种服务治理策略,保障服务的稳定性

  • 保障策略

    • 熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路(服务雪崩
    • 限流:保护被调用方,防止大流量把服务压垮
    • 超时控制:避免浪费资源在不可用节点上
  • 请求成功率

    • 负载均衡
    • 重试,重试由于会将流量导入另外一台物理机上,可能会有放大故障的风险
  • 长尾请求

    • 长尾请求总是会存在,造成长尾请求的原因包括网络抖动、GC、系统调度等

    • 预先设定阈值 t3,当Req1发出去t3时间都没有返回,直接发起重试请求Req2。相当于有两个请求同时运行,任何一个成功返回后就可以立即结束这次请求。整体耗时t4相比与超时后再请求,大大减少了时延

    image-20220524124112865.png

易用性

  • 开箱即用

    • 合理的默认参数选项、丰富的文档
  • 周边工具

    • 生成代码工具、脚手架工具

扩展性

  • Middleware:middleware 会被构造成一个有序调用链逐个执行,比如服务发现、路由、负载均衡、超时控制等
  • Option:作为初始化参数
  • 核心层是支持扩展的:编解码、协议、网络传输层
  • 代码生成工具也支持插件扩展

image-20220524124436210.png

观测性

  • 三件套:Log、Metric 和 Tracing

  • 内置观测性服务,用于观察框架内部状态

    • 当前环境变量
    • 配置参数
    • 缓存信息
    • 内置 pprof 服务用于排查问题

高性能

  • 连接池和多路复用:复用连接,减少频繁建联带来的开销
  • 高性能编解码协议:Thrift、Protobuf、Flatbuffer 和 Cap'n Proto 等
  • 高性能网络库:Netpoll 和 Netty 等