从零写分布式RPC框架 系列 2.0 (1)架构升级

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/alinyua/article/details/84351255

针对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编码器
  • 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

扫描RpcService注解
服务配置信息,如权重
服务实现类和服务限流配置
启动
收集服务信息
启动Netty服务器
和服务器自身信息一起注册到zk集群
交由RpcServerHandler管理负责方法实现和限流

RPC Client

ZKServiceDiscovery监听变化来维护本地服务地址列表
服务端利用反射执行方法生成结果
用户触发
根据负载均衡策略获取服务地址
执行远程过程调用
服务端返回结果
客户端拿到结果完成远程过程调用

其他

参考资料:
项目GitHub主页:https://github.com/linshenkx/rpc-netty-spring-boot-starter

猜你喜欢

转载自blog.csdn.net/alinyua/article/details/84351255
今日推荐