🥩 RPC

吞佛童子2022年10月10日
  • frame
  • RPC
大约 5 分钟

🥩 RPC

1. 整体架构

1) 结构图

  • 虚线
    • 初始化
  • 实线
    • 异步调用
  • 十字箭头
    • 同步调用

2) 组成部分

  1. 服务提供者 Provider
  2. 服务消费者 Consumer
  3. 注册中心 Registry
    • 非必须
  4. 监控中心 Monitor
    • 非必须

3) 连接形式说明

  • 注册中心 & 服务提供者 & 服务消费者 之间 长连接
  • 监控中心 & 服务提供者 & 服务消费者 之间 非长连接
  • 服务消费者 直接调用 服务提供者,不需要经过 注册中心
  • 即使 注册中心 & 监控中心 宕机,也不会影响到已经正常运行的 服务提供者 & 服务消费者
    • 服务消费者 本地缓存 服务提供者 的信息

4) 流程说明:

  1. 服务提供者 启动后,将自己可以提供的 服务列表信息 注册到 注册中心
  2. 服务消费者 启动后,向 注册中心 订阅想要的 服务
  3. 注册中心 将 服务提供者 元信息 通知给 服务消费者,当 注册中心 的服务列表发生改变时,注册中心 主动 向 服务消费者 推送 新的服务列表
  4. 服务消费者 从推送的服务列表中,按照 负载均衡算法 确定服务调用地址
  5. 服务消费者 通过 动态代理 的方式 远程过程调用 服务提供者 提供的服务
    • 服务消费者的 动态代理 模块会将远程调用需要的 接口名称、方法名称、方法的参数类型、方法的参数值 等信息 编码 & 序列化 成二进制字节流,然后网络传输给 服务提供者
  6. 服务提供者 根据 服务消费者 发来的数据,进行 二进制字节流的 解码,反序列化 成原始数据
  7. 服务提供者 根据 原始数据,调用相应服务,再将调用结果进行 编码 & 序列化,然后发送给 服务消费者
  8. 服务消费者 根据 服务提供者 发来的数据,对其进行 解码 & 反序列化,恢复为 原始数据,继续后续业务逻辑
  9. 服务提供者 & 服务消费者 记录调用的次数 & 时间,定期 将统计数据 发送给 监控中心

核心技术

1) 服务注册 & 发现

  • 注册中心 动态感知所有节点
  • 服务提供者 的服务列表发生变化时,主动推送给 服务消费者
  • 负载均衡
  • 常见注册中心
    • ZooKeeper
    • Nacos

负载均衡

  • 服务消费者 如何从 服务列表 中确定选择哪个 服务调用者
  • 常见负载均衡算法:
    • 轮询
    • 加权轮询
    • 最少连接数
    • 一致性 Hash

2) 序列化 & 反序列化

  • 对象是多维的,而数据流为 一维 的,因此需要将 对象类 压缩成 一维字节流 的形式
  • 常见序列化方式:
    • Protobuf
      • 文件小,传输效率高,支持多语言
    • Kryo
    • JSON
      • 字符型,用户友好,传输效率低
    • xml
      • 字符型,用户友好,传输效率低
    • 自定义

3) 网络传输 & 协议

  • 常用通信协议:
    • UDP
    • TCP
    • 自定义
  1. 常见的协议形式:
    • 固定长度
      • 效率高
      • 严格固定长度,长度不能超过限制,但若限制长度设置的过长,则数据无法填充满时需要填充
    • 特殊字符分隔
      • 长度自由
      • 只有遇到特殊字符时,才会解析前面的部分
    • header + body
      • header 长度固定,里面写明 body 长度;body 长度不定长
      • 解析时,先解析 header,得到 body 长度后,解析 body

调用方式

同步调用

  • 服务消费者 发起 RPC 调用后,线程一直阻塞,直到 服务提供者 返回结果 | 超时异常

异步调用

  • 服务消费者 发起 RPC 调用后,线程不阻塞,服务提供者的 返回结果 会被放入上下文中,服务消费者 可以执行其他操作,然后从 上下文 中得到这个结果

回调

  • 服务消费者 发起 RPC 调用后,会将 回调接口 Callback 对象发送给 RPC 框架,然后直接返回
  • 当 RPC 框架接收到 服务提供者的 返回结果 | 超时异常时,会执行 Callback 回调

单向调用

  • 服务消费者 发送 PRC 调用后,直接返回,不需要关心 是否调用成功

线程模型

  • 线程模型 分为 IO 线程 & 业务线程
    • IO 线程 负责 连接处理、数据编解码、数据传输
    • 业务线程 负责 业务逻辑处理
  • 服务端收到请求后,会解析请求得到信息,信息有 5 种派发策略
策略描述
all [default]所有信息均派发到 线程池,包括 请求、响应、连接事件、断开事件等
direct所有信息均 不派发到 线程池,全部在 IO 线程上直接执行
message只有 请求 & 响应 信息 派发到 线程池,其余消息在 线程池 执行
execution只有 请求信息 派发到 线程池,其余消息在 线程池 执行
connection在 IO 线程上,将 连接断开 事件压入队列,有序逐个执行,其他消息 派发到 线程池

动态代理

  • 常见动态代理
    • JDK 动态代理
    • Cglib 动态代理
    • javassist

监控

  • 监控统计调用时间 & 次数
上次编辑于: 2022/10/10 下午8:43:48
贡献者: liuxianzhishou