第一部分,設計分析
遠程調用要解決的主要問題:
1,序列化 : 如何將對象轉化為二進制數據進行傳輸,如何將二進制數據轉化對象
2,數據的傳輸(協議,第三方框架)
3,服務的注冊/發現,單點故障,分布式服務
4,服務的監控和管理
序列化的選擇:
可以使用java自帶的序列化,Hessian,protobuff,json,xml等
性能比較高的是protobuff和hessian,protobuff使用的時候需要編寫proto文件,有侵入性,比較麻煩,而Hessian
性能比protobuff稍差
不過近來出現了一個基於protobuff的框架:protostuff--不用編寫proto文件,基於注解,性能可以,推薦使用。
數據的傳輸:
出於並發性能的考慮,傳統的阻塞式 IO 顯然不太合適,因此我們需要異步的 IO,即 NIO。Java 提供了 NIO 的解決方案,Java 7 也提供了更優秀的 NIO.2 支持。可以選擇Netty或者mina來解決NIO數據傳輸的問題
使用ZooKeeper提供服務注冊與發現功能,解決單點故障以及分布式部署的問題(注冊中心)
需要單獨開發一個應用對服務進行監控和管理。
詳細的細節可以參看dubbo的文檔。
第二部分,設計樣例:
一,包設計。
1,common包用於封裝服務請求對象,服務響應對象以及基於protostuff的序列化工具
2,client包封裝服務的請求,開發服務消費者的時候需要依賴此包
3,registry包封裝服務的注冊以及發現
4,server包封裝請求的實際調用以及服務的發布
client和server均依賴common,registry
二,類設計
1,common包:
RpcRequest與RpcResponse為簡單javaBean,封裝RPC調用的請求和響應
SerializationUtil使用protostuff進行對象序列化操作,
RpcDecoder與RpcEncoder使用SerializationUtil和netty執行數據流的讀取和寫入(NIO傳輸)。
2,registry包
ServiceDiscovery負責服務的查找,返回
host:port
格式的服務提供地址數據
ServiceRegistry負責服務的注冊,以
host:port
的格式將服務的提供地址寫入到zookeeper
3,client包
RpcClient通過netty的NIO發起RPC請求並獲取服務的響應數據
RpcProxy負責:
封裝RPC請求對象
從服務注冊中心查找服務
代理RpcClient發起請求(使用java動態代理)
4,server包
RpcHandler實現io.netty.channel.SimpleChannelInboundHandler
完成Rpc請求的實際調用,通過反射調用方法(java reflect或者cglib)
RpcServer實現ApplicationContextAware, InitializingBean
通過讀取classpath中的spring-context文件依賴ServiceRegistry執行服務的注冊,當客戶端請求的時候
依賴RpcHandler完成調用。
第三部分,rpc服務的開發流程
1,分離接口與實現,api接口包為服務端和客戶端都必須依賴的接口,常量,javabean
2,服務端provider編寫實現類實現api包中的接口,依賴rpc-server包,classpath中放置spring配置文件,用於服務的注冊
3,客戶端consumer依賴rpc-client包,使用RpcProxy 創建接口實例執行調用
