ICE官方文檔中2.2【The Ice Architecture】章節(jié)翻譯之一 收藏
每次去參加各類大會(huì)或者培訓(xùn)之后,就下定決心說要好好學(xué)習(xí)英語,不過這個(gè)目標(biāo)還是一次次的沒有實(shí)現(xiàn);當(dāng)然工作忙、時(shí)間緊、沒語境……都成了有力的接口;但是這次偶想到一個(gè)退而求其次的方法,雖然沒有練習(xí)聽力的語境,但是我們可以先把英語翻譯能力練習(xí)起來,平時(shí)看英文doc的時(shí)間也不少,自認(rèn)為看大多數(shù)文檔都不存在啥障礙,但此次的要求是將他們翻譯出來,呵呵,別小看哦,能看懂和能翻譯出來可完全是兩個(gè)level!不信你也可以嘗試一把,呵呵;此次,正好遇到自己在看關(guān)于ICE相關(guān)的一些文檔,網(wǎng)上search了也沒有比較詳細(xì)點(diǎn)的中文資料,于是決定將其官方文檔中的架構(gòu)部分都翻譯出來,歡迎大家拋磚!
2.2.1 Introduction
ICE是一個(gè)面向?qū)ο蟮闹虚g件平臺(tái)。從根本上講,這就意味著ICE對(duì)于構(gòu)建面向?qū)ο蟮腃S結(jié)構(gòu)應(yīng)用程序提供Tool、Api、以及各類lib支持。ICE應(yīng)用程序非常適合于在各式各樣的環(huán)境下使用:客戶端和服務(wù)端可以分別用不同的編程語言來實(shí)現(xiàn),而且可以運(yùn)行在不同的操作系統(tǒng)和服務(wù)器架構(gòu)中,相互間的通信也可以使用各種網(wǎng)絡(luò)技術(shù)。
2.2.2 Terminology
每一種技術(shù)在其不斷演變、成熟過程中都會(huì)創(chuàng)造出一些特有的詞匯,當(dāng)然ICE也不例外,但是,被ICE使用的特有詞匯數(shù)量卻是非常少的。和發(fā)明新的術(shù)語相比,我們會(huì)更傾向于使用已經(jīng)存在的術(shù)語;如果你在過去曾經(jīng)使用過其他的中間件技術(shù),比如CORBA,那么你將會(huì)對(duì)接下來的內(nèi)容非常熟悉;
Clients and Servers
對(duì)于一個(gè)應(yīng)用程序,client、server分別對(duì)應(yīng)于哪個(gè)部分并沒有一致的規(guī)定;一般來說,他們是指在一次請(qǐng)求中扮演不同角色的特定應(yīng)用部分:
Client可以理解為主動(dòng)實(shí)體,他們負(fù)責(zé)向Server發(fā)起某個(gè)請(qǐng)求服務(wù);
Server可以理解為被動(dòng)實(shí)體,他們負(fù)責(zé)對(duì)Client請(qǐng)求進(jìn)行響應(yīng)并提供服務(wù);
通常,服務(wù)端并不是“純粹的”服務(wù)端【從來不發(fā)起請(qǐng)求,只負(fù)責(zé)對(duì)請(qǐng)求進(jìn)行響應(yīng)】;相反,服務(wù)端經(jīng)常扮演服務(wù)端和客戶端的雙重角色,而他們扮演客戶端的角色是為了滿足原客戶端的請(qǐng)求。
類似的,客戶端也不是“純粹的”客戶端【只負(fù)責(zé)發(fā)起請(qǐng)求,而不對(duì)請(qǐng)求進(jìn)行響應(yīng)】;相反,客戶端也經(jīng)常扮演雙重角色;比如,一個(gè)客戶端可能向服務(wù)端發(fā)起了一個(gè)耗時(shí)很長的請(qǐng)求,作為請(qǐng)求的一部分,該客戶端對(duì)服務(wù)端提供了一個(gè)回調(diào)【callback】對(duì)象,讓服務(wù)端在操作執(zhí)行完畢之后能夠通知到客戶端;在這個(gè)實(shí)例中,客戶端在請(qǐng)求發(fā)起時(shí)扮演了客戶端的角色,而在服務(wù)端執(zhí)行完畢之后通知客戶端時(shí)就扮演了服務(wù)端的角色。
類似上面的角色互換在很多系統(tǒng)中是非常普遍的,一般來說,CS類型的應(yīng)用系統(tǒng)更多的被準(zhǔn)確描述為點(diǎn)對(duì)點(diǎn)【Peer-to-Peer】系統(tǒng)。
ICE Objects
一個(gè)ICE對(duì)象是一個(gè)概念性的、抽象的實(shí)體。一般來說一個(gè)ICE對(duì)象具有如下一些特征:
它是一個(gè)本地的、或者是能對(duì)客戶端請(qǐng)求進(jìn)行響應(yīng)的遠(yuǎn)程地址空間的一個(gè)實(shí)體。
一個(gè)single ice對(duì)象能夠在一臺(tái)服務(wù)器上被實(shí)例化、或者在多臺(tái)服務(wù)器上被冗余的實(shí)例化;雖然一個(gè)對(duì)象有多個(gè)同時(shí)存在的實(shí)例,但他仍然是一個(gè)single ice對(duì)象。
每個(gè)ice對(duì)象有一個(gè)或者多個(gè)接口【interface】;接口就是一組操作【operation】組成的集合;客戶端通過調(diào)用接口來發(fā)起請(qǐng)求。
一個(gè)操作有零個(gè)或者多個(gè)參數(shù),返回值也一樣;參數(shù)和返回值都有一個(gè)特定的類型【type】;對(duì)于參數(shù)又分成兩類:輸入型參數(shù)【in-parameters】被客戶端初始化并傳給服務(wù)端;輸出型參數(shù)【out-parameters】被服務(wù)端初始化并傳給客戶端;返回值只不過是一種特殊的輸出型參數(shù)。
一個(gè)ice對(duì)象有一個(gè)能夠區(qū)別于其他對(duì)象的主接口;除此之外,一個(gè)ice對(duì)象還提供零個(gè)或者多個(gè)可選接口,這些可選接口被稱為facets;客戶端能夠選擇一個(gè)對(duì)象的facets中的其中一個(gè)來一起工作。
每個(gè)ice對(duì)象都有一個(gè)唯一的對(duì)象標(biāo)識(shí)【object identity】;一個(gè)對(duì)象的標(biāo)識(shí)就是讓他能夠區(qū)別于其他對(duì)象的標(biāo)識(shí)值;ice對(duì)象模型假設(shè)對(duì)象標(biāo)識(shí)都是全球唯一的,也就是說,在一個(gè)ice通信域里面,沒有兩個(gè)對(duì)象擁有相同的對(duì)象標(biāo)識(shí)。實(shí)際上,對(duì)象標(biāo)識(shí)并不一定要求使用類似UUID一樣的全球唯一標(biāo)識(shí),只需要在你自己的ice通信域里面保證任意的兩個(gè)對(duì)象標(biāo)識(shí)不沖突就可以了。
Proxies
客戶端若要和一個(gè)ice對(duì)象進(jìn)行通信,客戶端必須持有一個(gè)ice對(duì)象的代理【Proxy】;代理對(duì)于客戶端地址空間來說就像是本地對(duì)象一樣,對(duì)于客戶端而言,代理就代表著ice對(duì)象(可能是遠(yuǎn)程對(duì)象),對(duì)于一個(gè)ice對(duì)象來說,代理就是一個(gè)本地大使;ice中的代理和CORBA中的引用【Reference】是等價(jià)的,ice使用代理替換引用主要是為了避免混淆,因?yàn)橐靡呀?jīng)在各種不同的編程語言中有了太多其他的意思。當(dāng)客戶端對(duì)代理觸發(fā)一個(gè)操作時(shí),ice的運(yùn)行時(shí)會(huì)做如下的一些事情:
找到需要通信的ice對(duì)象;
若ice對(duì)象所在的服務(wù)器不在運(yùn)行狀態(tài)時(shí),嘗試激活他;
在服務(wù)器上激活ice對(duì)象;
傳輸輸入型參數(shù)給ice對(duì)象;
等待服務(wù)端操作完成;
返回輸出型參數(shù)、返回值給客戶端;當(dāng)遇到問題時(shí)會(huì)拋出一個(gè)異常;
為了完成如上所有步驟的操作,代理封裝了所有必要的信息;特別地,一個(gè)代理包括的信息有:
地址信息:允許客戶端運(yùn)行時(shí)能夠找到正確的服務(wù)器;
對(duì)象標(biāo)識(shí):能明確找到服務(wù)器上的具體某個(gè)特定對(duì)象;
可選的facet標(biāo)識(shí):確定代理需要關(guān)聯(lián)的某個(gè)特定facet;
Stringified Proxies
代理內(nèi)部包括的信息能夠被表示成一個(gè)字符串;比如,字符串
SimplePrinter:default -p 10000
就是一個(gè)代理的最具可讀性的表示;ice運(yùn)行時(shí)對(duì)此提供了api調(diào)用的支持,他允許把一個(gè)代理轉(zhuǎn)換成他的字符串化的形式,相反也是可以的。這是非常有用的,比如可以將代理保存在數(shù)據(jù)庫或者是文本文件中。
假設(shè)客戶端知道了一個(gè)ice對(duì)象的對(duì)象標(biāo)識(shí)、以及他的地址信息,那他就能靠提供的這些信息生成一個(gè)代理,就像無中生有一樣;換句話說,代理的內(nèi)部沒有任何不透明的信息;一個(gè)客戶端需要知道的僅僅是一個(gè)對(duì)象標(biāo)識(shí)、地址信息、以及對(duì)象的類型(當(dāng)需要觸發(fā)某個(gè)操作時(shí))。
Direct Proxies
直接代理是代理的一種類型,他嵌入了對(duì)象標(biāo)識(shí)、以及他的服務(wù)器所運(yùn)行的地址信息;完整的地址信息包括兩部分:
協(xié)議標(biāo)識(shí),比如TCP/IP、或者UDP;
協(xié)議指定的地址,比如主機(jī)名以及端口號(hào);
為了和直接代理后面的對(duì)象進(jìn)行通信,ice運(yùn)行時(shí)使用代理里面的地址信息去聯(lián)系服務(wù)器;然后客戶端每次發(fā)起請(qǐng)求時(shí)都會(huì)將該對(duì)象的標(biāo)識(shí)發(fā)送給服務(wù)端。
Indirect Proxies
間接代理有兩種形式:他只提供對(duì)象標(biāo)識(shí)、或者他只提供一個(gè)和對(duì)象標(biāo)識(shí)一起的對(duì)象適配標(biāo)識(shí)【object adapter identifier】。只通過他的對(duì)象標(biāo)識(shí)就能被訪問的對(duì)象成為知名對(duì)象【well-known object】;比如,字符串
SimplePrinter
就是一個(gè)被標(biāo)識(shí)為SimplePrinter的知名對(duì)象的有效代理。
一個(gè)包括對(duì)象適配標(biāo)識(shí)的間接代理有如下的字符串化的形式:
SimplePrinter@PrinterAdapter
該對(duì)象適配的所有對(duì)象均可以通過該代理被訪問,而不管該對(duì)象是否是知名對(duì)象。
注意:間接代理里面是不包括地址信息的。為了確定正確的服務(wù)器,客戶端ice運(yùn)行時(shí)將代理信息傳遞給定位服務(wù)【location service】;依次地,定位服務(wù)根據(jù)對(duì)象標(biāo)識(shí)或者對(duì)象適配標(biāo)識(shí)作為關(guān)鍵字,到包括了服務(wù)器地址信息的列表中查詢,然后返回正確的服務(wù)器地址信息給客戶端。這樣客戶端運(yùn)行時(shí)就知道怎樣和服務(wù)端進(jìn)行通信了。
以上的整個(gè)過程類似于DNS【domain name service】將域名轉(zhuǎn)換為IP;當(dāng)我們使用一個(gè)域名時(shí),比如打開www.zeroc.com去請(qǐng)求一個(gè)web頁面,主機(jī)名在后臺(tái)首先被解析成IP地址,一旦獲取到了正確的IP地址,就可以直接用來連接到正確的服務(wù)器上了。對(duì)ICE而言,除了映射是從一個(gè)對(duì)象標(biāo)識(shí)或者對(duì)象適配標(biāo)識(shí)找到對(duì)應(yīng)的協(xié)議地址對(duì),其他的都是非常類似的;客戶端運(yùn)行時(shí)通過配置信息知道如何聯(lián)系到定位服務(wù),就像web游覽器通過配置知道使用哪個(gè)DNS一樣。
Direct Versus Indirect Binding
從代理中相關(guān)信息解析成協(xié)議地址對(duì)的這個(gè)過程被稱為綁定;可以想象到,直接綁定是針對(duì)于直接代理的,而間接綁定就是針對(duì)間接代理的。
間接綁定的主要優(yōu)勢(shì)是他允許我們?cè)诓蛔儎?dòng)客戶端已經(jīng)持有的代理的情況下對(duì)服務(wù)器進(jìn)行變更(也即變更服務(wù)器地址);換句話說,直接代理可以避免定位到服務(wù)器的額外查詢,但是當(dāng)服務(wù)端變更到另外一臺(tái)機(jī)器時(shí),此時(shí)直接代理就失效了;而另一方面,間接代理是可以繼續(xù)工作的,即使我們移動(dòng)或者變更了服務(wù)器。
Fixed Proxies
固定代理也是代理的一種類型,他和一個(gè)特定的連接綁定;與包括地址信息或者適配名稱不同,固定代理包含了一個(gè)連接的句柄【Handle】。連接句柄只有在連接打開時(shí)有效,一旦連接關(guān)閉,代理也就不再有效;固定代理不能夠被【marshaled】,也就是說,他們不能被當(dāng)作參數(shù)在操作調(diào)用時(shí)進(jìn)行傳遞;固定代理經(jīng)常被用于雙向通信【bidirectional communication】,這樣服務(wù)端能夠在不重新打開一個(gè)新連接時(shí),直接對(duì)客戶端執(zhí)行回調(diào)【callback】操作。
Routed Proxies
路由代理將所有的請(qǐng)求都指向一個(gè)特定的目標(biāo)對(duì)象,而不是直接發(fā)送調(diào)用請(qǐng)求到一個(gè)實(shí)際對(duì)象;路由代理對(duì)于實(shí)現(xiàn)類似Glacier2服務(wù)時(shí)非常有用,因?yàn)樗茏尶蛻舳撕头?wù)端在防火墻的保護(hù)下進(jìn)行通信。
Replication
復(fù)制是讓對(duì)象適配器在多個(gè)地址有效的必要條件;復(fù)制的目標(biāo)是對(duì)相同服務(wù)端運(yùn)行在多個(gè)不同服務(wù)器上提供冗余;即使服務(wù)器中的某一臺(tái)出現(xiàn)了問題,在其他服務(wù)器上的服務(wù)端仍然有效。
特別的,復(fù)制的使用意味著:客戶端能夠通過一個(gè)地址訪問一個(gè)對(duì)象,也可以通過其他的地址而返回相同的結(jié)果;這些對(duì)象要么是無狀態(tài)的,要么他們的實(shí)現(xiàn)被設(shè)計(jì)成和數(shù)據(jù)庫保持同步,因?yàn)楦鱾€(gè)對(duì)象的狀態(tài)需要保持一致。
當(dāng)一個(gè)代理對(duì)一個(gè)對(duì)象指定多個(gè)地址時(shí),ice對(duì)此提供了有限的支持;在初始化連接時(shí),ice運(yùn)行時(shí)會(huì)隨機(jī)選擇地址空間中的其中一個(gè),而當(dāng)這個(gè)連接失效時(shí),運(yùn)行時(shí)則嘗試用其他地址進(jìn)行連接。比如,考慮如下這個(gè)代理:
SimplePrinter:tcp -h server1 -p 10001:tcp -h server2 -p 10002
該代理表明對(duì)象標(biāo)識(shí)為SimplePrinter、使用TCP協(xié)議、并在兩個(gè)地址server1和server2的對(duì)象是有效的;對(duì)于用戶或者系統(tǒng)管理員來說,最重要的就是確保服務(wù)端真正的運(yùn)行在不同端口號(hào)的服務(wù)器上。
Replica Groups
除了以上我們談到的基于代理的復(fù)制之外,ice還提供了被稱為復(fù)制集群【replica groups】的更有用的形式,他需要使用到定位服務(wù)。
一個(gè)復(fù)制集群有一個(gè)唯一的標(biāo)識(shí),且由任意數(shù)量的對(duì)象適配器組成;一個(gè)對(duì)象適配器只可能是最多一個(gè)復(fù)制集群的成員,這樣的適配器被稱為可復(fù)制對(duì)象適配器【replicated object adapter】。
一個(gè)復(fù)制集群被確定之后,他的標(biāo)識(shí)就可以被用在間接代理中替代適配器標(biāo)識(shí);比如,一個(gè)標(biāo)識(shí)為PrinterAdapters的復(fù)制集群可以被用在如下的代理:
SimplePrinter@PrinterAdapters
復(fù)制集群被定位服務(wù)視為一個(gè)“虛擬對(duì)象適配器”;當(dāng)解析一個(gè)包含復(fù)制集群標(biāo)識(shí)的間接代理時(shí),定位服務(wù)的行為就是一個(gè)實(shí)現(xiàn)細(xì)節(jié)。比如,一個(gè)定位服務(wù)能夠決定返回在集群內(nèi)的所有對(duì)象適配器的地址信息,此時(shí)客戶端ice運(yùn)行時(shí)就會(huì)在前面討論過的有限的復(fù)制方式中隨機(jī)選擇其中的某一個(gè)地址;另外一個(gè)可能性就是對(duì)于定位服務(wù)只返回唯一一個(gè)地址,這樣的決定將是依賴于啟發(fā)式的。
不管定位服務(wù)解析復(fù)制集群的方式如何,關(guān)鍵的收獲還是間接性的:在綁定過程中定位服務(wù)作為中間人能夠加入更多的智能化。
Servants
就像我們前面提到的,一個(gè)ice對(duì)象是一個(gè)概念性實(shí)體,他有類型、標(biāo)識(shí)、以及地址信息;不管怎樣,客戶端請(qǐng)求最終必須以一個(gè)確切的服務(wù)端處理實(shí)體而結(jié)束,該處理實(shí)體能夠提供對(duì)操作調(diào)用時(shí)的具體行為;說得更確切些【To put this differently】,一個(gè)客戶端請(qǐng)求最終必須以執(zhí)行服務(wù)端代碼結(jié)束,那些代碼用特定編程語言編寫,并且通過特定的處理器執(zhí)行。
伺服器就是在服務(wù)端能夠?qū)Σ僮鞅徽{(diào)用時(shí)提供相應(yīng)實(shí)際行為的artifact;一個(gè)伺服器對(duì)一個(gè)或者多個(gè)ice對(duì)象提供本體【substance】;在實(shí)際情況中,一個(gè)伺服器只不過是一個(gè)服務(wù)端開發(fā)人員編寫的類實(shí)例,該實(shí)例在服務(wù)端運(yùn)行時(shí)注冊(cè)成為一個(gè)或多個(gè)ice對(duì)象的伺服器;類中的方法就相當(dāng)于ice對(duì)象提供的接口中的操作,并對(duì)各操作提供具體的行為。
單個(gè)伺服器一次能依附于【incarnate】單個(gè)ice對(duì)象或者同時(shí)依附于多個(gè)ice對(duì)象;如果是前者,被伺服器依附的ice對(duì)象在伺服器中是明了的;如果是后者,伺服器隨著每次請(qǐng)求而根據(jù)ice對(duì)象標(biāo)識(shí)被提供,如此他就能決定在請(qǐng)求期間哪個(gè)對(duì)象會(huì)被依附。
與此相反的,單個(gè)ice對(duì)象可以擁有多個(gè)伺服器;比如,我們可能會(huì)為一個(gè)對(duì)象創(chuàng)造一個(gè)代理,該代理對(duì)不同的服務(wù)器有不同的地址;在這個(gè)情況中,我們有兩臺(tái)服務(wù)器,每臺(tái)服務(wù)器中對(duì)相同的ice對(duì)象包含一個(gè)伺服器;當(dāng)客戶端對(duì)該ice對(duì)象請(qǐng)求一個(gè)操作時(shí),客戶端運(yùn)行時(shí)會(huì)直接發(fā)送某個(gè)請(qǐng)求到確定的一個(gè)服務(wù)器;換句話說,對(duì)于單個(gè)ice對(duì)象的多個(gè)伺服器讓我們可以構(gòu)建具有冗余功能的系統(tǒng):客戶端運(yùn)行時(shí)企圖向某服務(wù)器發(fā)送一個(gè)請(qǐng)求時(shí),若此次請(qǐng)求失敗了,那么還可以將此次請(qǐng)求發(fā)送給另外一臺(tái)服務(wù)器;當(dāng)?shù)诙螄L試請(qǐng)求也失敗時(shí),客戶端應(yīng)用程序才會(huì)收到一個(gè)被服務(wù)端返回的錯(cuò)誤信息。
At-Most-Once Semantics
ice支持至多一次【at-most-once】語義:ice運(yùn)行時(shí)盡其所能去分發(fā)請(qǐng)求到正確的目的地,依賴于確切的環(huán)境他可能會(huì)對(duì)一次失敗的請(qǐng)求進(jìn)行重試;ice保證要么他對(duì)某個(gè)請(qǐng)求進(jìn)行分發(fā),要是他不能分發(fā)請(qǐng)求,此時(shí)他會(huì)明確告訴客戶端一個(gè)適當(dāng)?shù)漠惓#粚?duì)于一個(gè)請(qǐng)求絕不會(huì)【under no circumstances】被分發(fā)兩次,也即,重試只有在明確知道上次請(qǐng)求失敗的情況下才會(huì)發(fā)起(注意:通過UDP協(xié)議進(jìn)行的自帶尋址信息的觸發(fā)會(huì)是個(gè)例外,那種情況下,重復(fù)的UDP包會(huì)導(dǎo)致違反至多一次語義)。
支持至多一次語義是非常重要的,因?yàn)樗麄兡軌虮WC不是冥等【idempotent】的操作可以被安全的使用;所謂冥等操作是指某操作即使被執(zhí)行多次也返回相同的結(jié)果;比如,x = 1; 就是一個(gè)冥等操作;即使我們執(zhí)行兩次,返回的結(jié)果也都和前次的一樣。另一方面,x++; 該操作就不是冥等的:如果我們執(zhí)行該操作兩次,那結(jié)果就和第一次返回的結(jié)果是不一樣的。
如果不支持至多一次語義,我們可以針對(duì)網(wǎng)絡(luò)失敗構(gòu)建出更加健壯的分布式系統(tǒng);然而,現(xiàn)實(shí)系統(tǒng)需要支持非冥等操作,所以至多一次語義是必要的,即使他們因此而降低了系統(tǒng)的健壯性。ice允許將個(gè)別操作標(biāo)識(shí)為冥等的,對(duì)此類操作,ice運(yùn)行時(shí)使用相對(duì)于非冥等操作更具侵入性的錯(cuò)誤恢復(fù)機(jī)制。
Synchronous Method Invocation
默認(rèn)情況下,ice的請(qǐng)求分發(fā)模型是同步的遠(yuǎn)程過程調(diào)用【remote procedure call】:此時(shí)操作調(diào)用時(shí)的行為就像是本地過程調(diào)用一樣,也即,客戶端線程在操作調(diào)用期間被暫緩【suspend】直到調(diào)用完全結(jié)束。
Asynchronous Method Invocation
ice也知道異步方法觸發(fā)【AMI】:客戶端能夠異步地調(diào)用某個(gè)操作,也即客戶端照常使用一個(gè)代理去觸發(fā)某個(gè)操作,但是除了傳遞普通參數(shù)之外,還需要傳遞回調(diào)對(duì)象,而且客戶端觸發(fā)是立刻返回的。一旦操作完成了,服務(wù)端運(yùn)行時(shí)觸發(fā)由客戶端初始傳入的回調(diào)對(duì)象中的方法,然后將操作結(jié)果傳給回調(diào)對(duì)象(若處理失敗,則傳遞異常信息給回調(diào)對(duì)象)。
服務(wù)端并不能辨別以同步方式或者其他方式請(qǐng)求的異步觸發(fā),服務(wù)端只是知道客戶端對(duì)某個(gè)對(duì)象觸發(fā)了一次操作而已。
Asynchronous Method Dispatch
AMD是服務(wù)端的AMI;對(duì)于默認(rèn)的同步分發(fā),服務(wù)端運(yùn)行時(shí)直接定位到服務(wù)器內(nèi)的應(yīng)用程序代碼對(duì)觸發(fā)的操作進(jìn)行響應(yīng);在操作執(zhí)行期間,服務(wù)端的某個(gè)執(zhí)行線程被完全占用,當(dāng)操作完成時(shí)被釋放。
對(duì)于異步分發(fā)【AMD】,當(dāng)客戶端的某個(gè)操作觸發(fā)到達(dá)服務(wù)端時(shí),服務(wù)端的應(yīng)用程序代碼被告知;但是與AMI中代碼立刻去處理請(qǐng)求不同,服務(wù)端應(yīng)用可以選擇延遲對(duì)請(qǐng)求的處理,如此他就釋放了針對(duì)請(qǐng)求的執(zhí)行線程;此時(shí)服務(wù)端應(yīng)用程序代碼就可以去做任意的他想做的;最后,一旦操作的結(jié)果可用了,應(yīng)用程序代碼通過調(diào)用api通知服務(wù)端ice運(yùn)行時(shí)前面被分發(fā)過來的餓請(qǐng)求已經(jīng)處理完成了,然后ice運(yùn)行時(shí)將操作的結(jié)果返回給客戶端。
AMD是非常有用的,比如服務(wù)端提供了一個(gè)執(zhí)行非常耗時(shí)的操作給客戶端,或者服務(wù)端的某個(gè)操作是需要從其他額外的數(shù)據(jù)源中去異步的讀取數(shù)據(jù)并將其返回給客戶端;對(duì)于同步分發(fā)【SD】,每個(gè)客戶端需要一直等待服務(wù)端執(zhí)行線程返回的數(shù)據(jù);顯然,該方法對(duì)于有很多個(gè)客戶端時(shí)是非常不具有可擴(kuò)展性的;對(duì)于異步分發(fā),成千上萬的客戶端可以對(duì)某個(gè)相同的操作進(jìn)行請(qǐng)求觸發(fā),但卻不會(huì)完全占用服務(wù)端的任何執(zhí)行線程。
AMD的另外一個(gè)使用場景是:當(dāng)完成某個(gè)操作并將操作結(jié)果返回給客戶端時(shí),此次卻還需要繼續(xù)保持服務(wù)端執(zhí)行線程去做一些其他事情,比如執(zhí)行cleanup或者是更新持久層存儲(chǔ)等。
同步和異步分發(fā)對(duì)于客戶端而言是完全透明的,客戶端不可能告訴服務(wù)器是采用同步還是異步的方式去處理一個(gè)請(qǐng)求。
Oneway Method Invocation
客戶端能夠通過單向請(qǐng)求的方式來調(diào)用操作;單向觸發(fā)【oneway invocation】支持“best effort”語義;對(duì)于單向觸發(fā),客戶端運(yùn)行時(shí)將請(qǐng)求傳遞給local transport,只要被local transport緩沖器記錄了,那對(duì)于客戶端的請(qǐng)求就完成了;而實(shí)際的觸發(fā)請(qǐng)求隨后會(huì)被操作系統(tǒng)異步的發(fā)送;對(duì)于單向觸發(fā),服務(wù)器并不進(jìn)行響應(yīng),也即,流量只是從客戶端向服務(wù)端的,而服務(wù)端到客戶端卻是沒有的。
單向請(qǐng)求是不可靠的;比如,目標(biāo)對(duì)象可能不存在,此時(shí)請(qǐng)求就被丟失掉了;類似的,該操作可能被分發(fā)給服務(wù)器上的某個(gè)伺服器,但是操作卻可能會(huì)失敗(比如參數(shù)非法);即使這樣,客戶端仍然無法接收到任何關(guān)于出錯(cuò)的通知信息。
單向請(qǐng)求只可能適用于沒有返回者、沒有輸出型參數(shù)、不會(huì)拋出用戶級(jí)異常這類型的操作。
對(duì)于服務(wù)端的應(yīng)用程序代碼而言,單向請(qǐng)求是透明的,也即,沒有任何方法可以區(qū)分從一個(gè)單向請(qǐng)求發(fā)起的雙向調(diào)用。
單向請(qǐng)求只對(duì)提供了基于流的傳輸協(xié)議(比如TCP/IP/SSL)的目標(biāo)對(duì)象有效。
注意:即使單向請(qǐng)求通過基于流的傳輸協(xié)議進(jìn)行發(fā)送,他們?cè)诜?wù)端被處理時(shí)有可能是無序的;這是因?yàn)槊看握{(diào)用都是在他自己所在線程中被分發(fā)的;即使請(qǐng)求到達(dá)服務(wù)端時(shí)請(qǐng)求在被初始化時(shí)進(jìn)行了排序,那也不意味著他們將會(huì)按照那個(gè)順序被處理--線程調(diào)用的異常行為可能會(huì)導(dǎo)致某個(gè)單向請(qǐng)求比另外一個(gè)比他更早到達(dá)的單向請(qǐng)求早完成。
Batched Oneway Method Invocation
每個(gè)單向請(qǐng)求都發(fā)送一個(gè)獨(dú)立的消息給服務(wù)器;對(duì)于一系列短消息而言,這樣做的代價(jià)是相當(dāng)高的:因?yàn)閷?duì)于每條消息客戶端和服務(wù)端運(yùn)行時(shí)都必須在用戶模式和內(nèi)核模式之間進(jìn)行切換;在網(wǎng)絡(luò)層面,每條消息都會(huì)帶來流控制和消息確認(rèn)的代價(jià)。
批量單向請(qǐng)求【Batched oneway invocations】允許以單條信息的方式發(fā)送一系列的單向請(qǐng)求:每次觸發(fā)一個(gè)批量單向操作時(shí),請(qǐng)求都會(huì)在客戶端運(yùn)行時(shí)被緩存,一旦你將所有需要發(fā)送的單向請(qǐng)求都累計(jì)在一起了,你可以通過調(diào)用一個(gè)獨(dú)立的api一次將所有的請(qǐng)求都發(fā)送完畢;隨后客戶端運(yùn)行時(shí)在一條消息內(nèi)將所有已經(jīng)緩存起來的請(qǐng)求發(fā)送給服務(wù)器,服務(wù)器也以一條消息的形式接收到所有的觸發(fā)請(qǐng)求;這就避免了客戶端和服務(wù)端不斷重復(fù)的切換內(nèi)核,在網(wǎng)絡(luò)傳輸上也更加容易,因?yàn)橐粭l大的消息體被傳輸要比很多小信息體傳輸高效得多。
一個(gè)批量單向信息中的單個(gè)請(qǐng)求被一個(gè)單獨(dú)線程按照他們加入該批次的順序進(jìn)行分發(fā);這就保證了在一個(gè)批次的單向信息被服務(wù)器處理時(shí)是有序的。
批量單向請(qǐng)求對(duì)于消息服務(wù)特別有用,比如IceStorm。
Datagram Invocations
數(shù)據(jù)包請(qǐng)求與單向請(qǐng)求有著類似的“best effort”語義;但是,數(shù)據(jù)包請(qǐng)求需要對(duì)象使用UDP作為傳輸協(xié)議,而單向請(qǐng)求采用TCP/IP。
就像單向請(qǐng)求,數(shù)據(jù)包請(qǐng)求也需要操作沒有返回值、輸出型參數(shù)、用戶級(jí)異常;數(shù)據(jù)包請(qǐng)求通過UDP協(xié)議去觸發(fā)某個(gè)操作,只要本地UDP堆棧接收到消息操作就返回了;而實(shí)際的操作調(diào)用在后臺(tái)被網(wǎng)絡(luò)堆棧異步的發(fā)送。
數(shù)據(jù)包請(qǐng)求也是不可靠的,就像單向請(qǐng)求一樣。
和單向請(qǐng)求不一樣的是,數(shù)據(jù)包請(qǐng)求有很多額外的錯(cuò)誤描述:
個(gè)別請(qǐng)求可能在網(wǎng)絡(luò)層被丟失;這是因?yàn)閁DP包投遞的不可靠性所致;比如,若依次觸發(fā)三個(gè)操作,中間的那個(gè)操作可能就會(huì)被丟失;類似的事情在單向請(qǐng)求中就不可能出現(xiàn),因?yàn)樗麄兪腔谶B接的傳輸協(xié)議進(jìn)行分發(fā)的,個(gè)別請(qǐng)求不可能丟失。
個(gè)別請(qǐng)求可能無序到達(dá);這也是因?yàn)閁DP的特性所致;因?yàn)槊總€(gè)請(qǐng)求作為一個(gè)單獨(dú)的數(shù)據(jù)包進(jìn)行發(fā)送,數(shù)據(jù)包在網(wǎng)絡(luò)上可能通過不同路徑傳輸,這樣請(qǐng)求到達(dá)時(shí)的順序就可能和他們被發(fā)送時(shí)的順序是不一樣的。
數(shù)據(jù)包請(qǐng)求非常適合于在LANs中發(fā)送小消息,此時(shí)丟失率是很低的;他們也適合于低延遲比可靠性更重要的應(yīng)用場景,比如針對(duì)快速、交互式的應(yīng)用程序;最后,數(shù)據(jù)包請(qǐng)求能夠被用于同時(shí)向多臺(tái)服務(wù)器組播消息。
Batched Datagram Invocations
關(guān)于批量單向請(qǐng)求,批量數(shù)據(jù)包請(qǐng)求允許在緩沖器中收集很多的請(qǐng)求,然后通過調(diào)用api將整個(gè)緩沖器中數(shù)據(jù)作為一個(gè)數(shù)據(jù)包進(jìn)行發(fā)送,之后清除緩沖器;批量數(shù)據(jù)包降低了重復(fù)系統(tǒng)的調(diào)用,還允許底層網(wǎng)絡(luò)更加有效的運(yùn)行;但是,批量數(shù)據(jù)包請(qǐng)求只對(duì)批量消息的容量未超過網(wǎng)絡(luò)的協(xié)議數(shù)據(jù)單元【PDU】時(shí)有用;如果一個(gè)批量數(shù)據(jù)包的容量太大,將會(huì)被拆分成多個(gè)數(shù)據(jù)片段,這樣一個(gè)或者多個(gè)數(shù)據(jù)片段可能會(huì)被丟失,從而導(dǎo)致整個(gè)批量消息的丟失;然而,有一點(diǎn)是可以保證的,即一個(gè)批量數(shù)據(jù)包中的所有請(qǐng)求要么被分發(fā),要么都不被分發(fā),一個(gè)批次中某個(gè)請(qǐng)求被丟失是不可能的。
在服務(wù)端批量數(shù)據(jù)包使用一個(gè)單獨(dú)的線程來分發(fā)各批次中的各個(gè)請(qǐng)求;這就保證了在一個(gè)批次中各請(qǐng)求是被有序的執(zhí)行,在服務(wù)端請(qǐng)求不可能出現(xiàn)重新排序的現(xiàn)象。
Run-Time Exceptions
任何的操作調(diào)用都可能引發(fā)運(yùn)行時(shí)異常;運(yùn)行時(shí)異常是被ice運(yùn)行時(shí)預(yù)先定義好的、且覆蓋了通用的錯(cuò)誤情況,比如連接失敗、連接超時(shí)、資源分配失敗;對(duì)于應(yīng)用程序而言,運(yùn)行時(shí)異常就像本地異常一樣,這樣對(duì)于具有異常處理能力的編程語言具有的本地異常處理進(jìn)行了優(yōu)美的集成。
User Exceptions
用戶級(jí)異常被使用來標(biāo)示依賴于客戶端的應(yīng)用程序特定的錯(cuò)誤;用戶級(jí)異常能夠攜帶任意的復(fù)雜數(shù)據(jù),且能夠被繼承,這樣就使得客戶端能夠通過捕獲繼承體系中的某個(gè)異常,從而很容易的處理錯(cuò)誤類別。
Properties
ice運(yùn)行時(shí)中的很多參數(shù)都可以通過properties文件來進(jìn)行配置;Properties是一個(gè)鍵值對(duì)【name-value pair】,比如Ice.Default.Protocol = tcp; Properties一般被存儲(chǔ)在文本文件中,然后被運(yùn)行時(shí)解析,比如線程池大小,跟蹤級(jí)別、以及其他各種配置參數(shù)。
?
本文來自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/sfdev/archive/2008/12/04/3446640.aspx