rpc是遠(yuǎn)程過程調(diào)用的簡稱,廣泛應(yīng)用在大規(guī)模分布式應(yīng)用中,作用是有助于系統(tǒng)的垂直拆分,使系統(tǒng)更易拓展。java中的rpc框架比較多,各有特色,廣泛使用的有rmi、hessian、dubbo等。rpc還有一個(gè)特點(diǎn)就是能夠跨語言,本文只以java語言里的rpc為例。
對于rpc有一個(gè)邏輯關(guān)系圖,以rmi為例:
其他的框架結(jié)構(gòu)也類似,區(qū)別在于對象的序列化方法,傳輸對象的通訊協(xié)議,以及注冊中心的管理與failover設(shè)計(jì)(利用zookeeper)。
客戶端和服務(wù)端可以運(yùn)行在不同的jvm中,client只需要引入接口,接口的實(shí)現(xiàn)以及運(yùn)行時(shí)需要的數(shù)據(jù)都在server端,rpc的主要依賴技術(shù)是序列化、反序列化和傳輸協(xié)議,java里對應(yīng)的就是對象的序列化、反序列化以及序列化后數(shù)據(jù)的傳輸。rmi的序列化和反序列化是java自帶的,hessian里的序列化和反序列化是私有的,傳輸協(xié)議則是http,dubbo的序列化可以多種選擇,一般使用hessian的序列化協(xié)議,傳輸則是tcp協(xié)議,使用了高性能的nio框架netty。對于序列化,我還了解一些,像google的probuffer、jboss marshalling和apache thrift等,之前有寫一篇介紹probuffer的博文
1、rmi(遠(yuǎn)程方法調(diào)用)
java自帶的遠(yuǎn)程方法調(diào)用工具,不過有一定的局限性,畢竟是java語言最開始時(shí)的設(shè)計(jì),后來很多框架的原理都基于rmi,rmi的使用如下:
對外接口
1
2
3
4
5
|
public interface iservice extends remote { public string queryname(string no) throws remoteexception; }</span> |
服務(wù)實(shí)現(xiàn)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
import java.rmi.remoteexception; import java.rmi.server.unicastremoteobject; // 服務(wù)實(shí)現(xiàn) public class serviceimpl extends unicastremoteobject implements iservice { /** */ private static final long serialversionuid = 682805210518738166l; /** * @throws remoteexception */ protected serviceimpl() throws remoteexception { super (); } /* (non-javadoc) * @see com.suning.ebuy.wd.web.iservice#queryname(java.lang.string) */ @override public string queryname(string no) throws remoteexception { // 方法的具體實(shí)現(xiàn) system.out.println( "hello" + no); return string.valueof(system.currenttimemillis()); } } |
rmi客戶端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import java.rmi.remoteexception; import java.rmi.registry.locateregistry; import java.rmi.registry.registry; // rmi服務(wù)端 public class server { public static void main(string[] args) { // 注冊管理器 registry registry = null ; try { // 創(chuàng)建一個(gè)服務(wù)注冊管理器 registry = locateregistry.createregistry( 8088 ); } catch (remoteexception e) { } try { // 創(chuàng)建一個(gè)服務(wù) serviceimpl server = new serviceimpl(); // 將服務(wù)綁定命名 registry.rebind( "vince" , server); system.out.println( "bind server" ); } catch (remoteexception e) { } } } |
服務(wù)注冊管理器寫在了server里,當(dāng)然也可以抽出來單獨(dú)作為一個(gè)服務(wù),在其他一些框架中,往往用zookeeper充當(dāng)注冊管理角色。
2、hessian(基于http的遠(yuǎn)程方法調(diào)用)
基于http協(xié)議傳輸,在性能方面還不夠完美,負(fù)載均衡和失效轉(zhuǎn)移依賴于應(yīng)用的負(fù)載均衡器,hessian的使用則與rmi類似,區(qū)別在于淡化了registry的角色,通過顯示的地址調(diào)用,利用hessianproxyfactory根據(jù)配置的地址create一個(gè)代理對象,另外還要引入hessian的jar包。
3、dubbo(淘寶開源的基于tcp的rpc框架)
基于nio框架netty的高性能rpc框架,是阿里巴巴開源的,總體原理如下:
在了解dubbo之前,要先對zookeeper有深入的理解,當(dāng)理解了zookeeper后,dubbo也就了無秘密了。
zookeeper作為dubbo服務(wù)的注冊中心,dubbo原先基于數(shù)據(jù)庫的注冊中心,沒采用zookeeper,zookeeper一個(gè)分布式的服務(wù)框架,是樹型的目錄服務(wù)的數(shù)據(jù)存儲(chǔ),能做到集群管理數(shù)據(jù) ,這里能很好的作為dubbo服務(wù)的注冊中心,dubbo能與zookeeper做到集群部署,當(dāng)提供者出現(xiàn)斷電等異常停機(jī)時(shí),zookeeper注冊中心能自動(dòng)刪除提供者信息,當(dāng)提供者重啟時(shí),能自動(dòng)恢復(fù)注冊數(shù)據(jù),以及訂閱請求。
dubbo的詳細(xì)說明在淘寶開源里說的非常詳細(xì),在工作中很多生產(chǎn)項(xiàng)目都用了dubbo,過程中也發(fā)現(xiàn)了很多需要注意的地方,尤其是那繁多的配置,設(shè)置不當(dāng)都會(huì)讓人煩腦,最好能再基于現(xiàn)有開源的dubbo再定制優(yōu)化一下。
原文鏈接:http://blog.csdn.net/volts/article/details/54672525