针对1.0版本的性能问题,本版本做了从服务地址列表缓存等方面做了优化处理,并加入负载均衡引擎、序列化引擎、服务端限流等新功能,并对通信模型进行改造,使其支持新特性、避免粘包半包问题并对后续升级改造留下支持空间。具体可见 项目GitHub地址 。本文将介绍 2.0 版本的逻辑架构和模型设计,部分内容在 从零写分布式RPC框架 系列 1.0 (1)架构设计 已有说明,此处不再赘述。
系列文章:
专栏:从零开始写分布式RPC框架
项目GitHub地址:https://github.com/linshenkx/rpc-netty-spring-boot-starter
手写通用类型负载均衡路由引擎(含随机、轮询、哈希等及其带权形式)
实现 序列化引擎(支持 JDK默认、Hessian、Json、Protostuff、Xml、Avro、ProtocolBuffer、Thrift等序列化方式)
从零写分布式RPC框架 系列 2.0 (1)架构升级
从零写分布式RPC框架 系列 2.0 (2)RPC-Common模块设计实现
从零写分布式RPC框架 系列 2.0 (3)RPC-Server和RPC-Client模块改造
从零写分布式RPC框架 系列 2.0 (4)使用BeanPostProcessor实现自定义@RpcReference注解注入
文章目录
0 版本说明
- 增加负载均衡路由策略引擎(含随机、轮询、哈希等及其带权形式)
- 增加序列化引擎(支持 JDK默认、Hessian、Json、Protostuff、Xml、Avro、ProtocolBuffer、Thrift等序列化方式)
- 服务提供者提供服务时可注解参数指定最大工作线程数来限流
- 服务消费者对服务地址列表进行缓存,并监听变化
- 传输协议修改,使用消息头+消息体的模式以支持新特性并避免粘包半包问题和留下扩展空间
一 逻辑架构
总体结构不变,但3个主要模块都有较大的变化。
(1) RPC-Common 模块
将 RPC-Server 和 RPC-Client 模块的部分功能(如Netty的处理器)收回,并添加大量新功能支持。是本次版本的主要升级对象。
其模块内容大致如下:
- annotation
- RpcService:RPC服务注解,由服务提供者使用
- bean
- BodyContent接口:RpcRequest和RpcResponse的接口类,代表消息体内容
- RpcRequest:Rpc请求时的消息体内容
- RpcResponse:Rpc应答时的消息体内容
- codec
- decode
- RemotingTransporterDecoder:远程传输实体的Netty解码器
- encode
- RemotingTransporterEncoder:远程传输实体的Netty编码器
- decode
- exception:自定义异常包
- handler
- RpcClientHandler:Rpc客户端Netty处理器,由服务消费者使用
- RpcServerHandler:Rpc服务端Netty处理器,由服务提供者使用
- properties
- ZKProperties:ZK属性配置类,由服务提供者和服务消费者共用
- protocal.xuan
- RemotingTransporter:远程传输实体类,完成协议定制(magic+flag+invokeId+bodyLength+bodyContent)
- route
路由引擎,由服务消费者使用,在客户端实现负载均衡。详情可见:手写通用类型负载均衡路由引擎(含随机、轮询、哈希等及其带权形式) - serialization
序列化引擎,由服务消费者使用,由客户端选择合适序列化格式。详情可见:实现 序列化引擎(支持 JDK默认、Hessian、Json、Protostuff、Xml、Avro、ProtocolBuffer、Thrift等序列化方式)
(2) RPC-Server 模块
配合 RPC-Common 模块完成新功能,并逐渐精简。
主要变化在于 RpcServer,增加 serviceRpcServiceMap 管理 Rpc服务信息,增加 serviceSemaphoreMap 管理Rpc服务限流信息。
(3) RPC-Client 模块
配合 RPC-Common 模块完成新功能,并强化 ZKServiceDiscovery ZK注册中心能力,使其负责对zk集群上的服务地址进行监听,维护本地缓存的服务地址表。并且依赖RPC-Client支持,授予RpcClient根据配置文件自由选择负载均衡策略和序列化方式的能力。
二 模型设计
(1) 通信协议 RemotingTransporter+XuanProtocol
使用 消息头+消息体的形式,相关设计参考自dubbo
字段名 | magic | flag | invokeId | bodylength | bodyContent |
---|---|---|---|---|---|
含义 | 魔数 | 标志位 | 请求ID | 消息体长度 | 消息体 |
长度 | 2字节 | 1 字节 | 8字节 | 4字节 | 不定长 |
作用 | 标识独有协议 | 标识 是否请求、是否双向、是否为ping请求、是否为其他(保留位)以及序列化方式 | 标识唯一请求 | 标识消息体长度,避免粘包半包 | 存放RpcRequest或RpcResponse内容 |
(2)工作流程图
RPC Server
RPC Client
其他
参考资料:
项目GitHub主页:https://github.com/linshenkx/rpc-netty-spring-boot-starter