針對1.0版本的性能問題,本版本做了從服務地址列表緩存等方面做了優化處理,並加入負載均衡引擎、序列化引擎、服務端限流等新功能,並對通信模型進行改造,使其支持新特性、避免粘包半包問題並對後續升級改造留下支持空間。具體可見 項目GitHub地址 。本文將介紹 2.0 版本的邏輯架構和模型設計,部分內容在 從零寫分佈式RPC框架 系列 1.0 (1)架構設計 已有說明,此處不再贅述。
系列文章:
手寫通用類型負載均衡路由引擎(含隨機、輪詢、哈希等及其帶權形式)
實現 序列化引擎(支持 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模塊改造
文章目錄
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