🥩 RPC
2022年10月10日
- frame
🥩 RPC
1. 整体架构
1) 结构图
- 虚线
- 初始化
- 实线
- 异步调用
- 十字箭头
- 同步调用
2) 组成部分
- 服务提供者
Provider
- 服务消费者
Consumer
- 注册中心
Registry
- 非必须
- 监控中心
Monitor
- 非必须
3) 连接形式说明
注册中心
&服务提供者
&服务消费者
之间 长连接监控中心
&服务提供者
&服务消费者
之间 非长连接服务消费者
直接调用服务提供者
,不需要经过注册中心
- 即使
注册中心
&监控中心
宕机,也不会影响到已经正常运行的服务提供者
&服务消费者
服务消费者
本地缓存服务提供者
的信息
4) 流程说明:
服务提供者
启动后,将自己可以提供的 服务列表信息 注册到注册中心
服务消费者
启动后,向注册中心
订阅想要的 服务注册中心
将服务提供者
元信息 通知给服务消费者
,当注册中心
的服务列表发生改变时,注册中心
主动 向服务消费者
推送 新的服务列表服务消费者
从推送的服务列表中,按照 负载均衡算法 确定服务调用地址服务消费者
通过 动态代理 的方式 远程过程调用服务提供者
提供的服务服务消费者的
动态代理 模块会将远程调用需要的 接口名称、方法名称、方法的参数类型、方法的参数值 等信息 编码 & 序列化 成二进制字节流,然后网络传输给服务提供者
服务提供者
根据服务消费者
发来的数据,进行 二进制字节流的 解码,反序列化 成原始数据服务提供者
根据 原始数据,调用相应服务,再将调用结果进行 编码 & 序列化,然后发送给服务消费者
服务消费者
根据服务提供者
发来的数据,对其进行 解码 & 反序列化,恢复为 原始数据,继续后续业务逻辑服务提供者
&服务消费者
记录调用的次数 & 时间,定期 将统计数据 发送给监控中心
核心技术
1) 服务注册 & 发现
- 注册中心 动态感知所有节点
- 服务提供者 的服务列表发生变化时,主动推送给 服务消费者
- 负载均衡
- 常见注册中心
- ZooKeeper
- Nacos
负载均衡
- 服务消费者 如何从 服务列表 中确定选择哪个 服务调用者
- 常见负载均衡算法:
- 轮询
- 加权轮询
- 最少连接数
- 一致性 Hash
2) 序列化 & 反序列化
- 对象是多维的,而数据流为 一维 的,因此需要将 对象类 压缩成 一维字节流 的形式
- 常见序列化方式:
- Protobuf
- 文件小,传输效率高,支持多语言
- Kryo
- JSON
- 字符型,用户友好,传输效率低
- xml
- 字符型,用户友好,传输效率低
- 自定义
- Protobuf
3) 网络传输 & 协议
- 常用通信协议:
- UDP
- TCP
- 自定义
- 常见的协议形式:
- 固定长度
- 效率高
- 严格固定长度,长度不能超过限制,但若限制长度设置的过长,则数据无法填充满时需要填充
- 特殊字符分隔
- 长度自由
- 只有遇到特殊字符时,才会解析前面的部分
- 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
监控
- 监控统计调用时间 & 次数