第一部分,設計分析
遠程調用要解決的主要問題:java
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傳輸)。
ServiceDiscovery負責服務的查找,返回
ServiceRegistry負責服務的註冊,以
的格式將服務的提供地址寫入到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 建立接口實例執行調用