🥩 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