1 介紹
????????遠(yuǎn)程過(guò)程調(diào)用似乎是一種有用的范式,用于在以高級(jí)語(yǔ)言編寫的程序之間提供跨網(wǎng)絡(luò)的通信。本文描述一個(gè)提供了遠(yuǎn)程調(diào)用工具的軟件包,面對(duì)這樣一個(gè)軟件包時(shí)一個(gè)設(shè)計(jì)者擁有的選項(xiàng),以及我們做出的選擇。我們描述了我們的RPC機(jī)制的整體結(jié)構(gòu),用于綁定RPC客戶端的工具,傳輸通信層協(xié)議,以及一些性能測(cè)量。包括用于實(shí)現(xiàn)高性能和最小化集群間負(fù)載的一些優(yōu)化的描述。
1.1 背景
????????遠(yuǎn)程過(guò)程調(diào)用(以下稱RPC)的概念是非常簡(jiǎn)單的。它是基于這一觀察:過(guò)程調(diào)用是一個(gè)眾所周知且易于理解的機(jī)制,用于在單個(gè)計(jì)算機(jī)上運(yùn)行的程序內(nèi)的控制和數(shù)據(jù)的傳輸。因此提出擴(kuò)展這種機(jī)制以提供跨網(wǎng)絡(luò)的控制和數(shù)據(jù)的傳輸。但一個(gè)遠(yuǎn)程程序被調(diào)用時(shí),該調(diào)用環(huán)境會(huì)被掛起,參數(shù)通過(guò)網(wǎng)絡(luò)傳輸?shù)皆摮绦虮徽{(diào)用的環(huán)境中(我們將之稱為被調(diào)用者),并在那里執(zhí)行相應(yīng)的程序。當(dāng)程序執(zhí)行結(jié)束并產(chǎn)生結(jié)果時(shí),結(jié)果再被傳回調(diào)用環(huán)境中。此時(shí)調(diào)用環(huán)境中的執(zhí)行恢復(fù),仿佛是在單機(jī)上執(zhí)行調(diào)用一樣。當(dāng)調(diào)用環(huán)境被掛起時(shí),該機(jī)器上的其他進(jìn)程可能仍然在執(zhí)行——這取決于該環(huán)境的并行性和RPC的實(shí)現(xiàn)。
????????這個(gè)想法還有很多吸引人的方面。一個(gè)是其干凈和簡(jiǎn)潔的方言(語(yǔ)義):這使得正確地構(gòu)建分布式計(jì)算變得更容易。另外一個(gè)就是效率:過(guò)程調(diào)用對(duì)于快速的通信來(lái)說(shuō)也足夠簡(jiǎn)單。第三個(gè)就是通用性:在單機(jī)計(jì)算中,過(guò)程通常是算法各部分間通信的最終要的機(jī)制。
????????RPC這一概念已存在多年了。至少?gòu)?976年以來(lái),它已經(jīng)在公共文學(xué)中被多次討論過(guò)。Nelson的博士論文是對(duì)RPC系統(tǒng)設(shè)計(jì)可能性的廣泛研究,而且參考了大量的以前關(guān)于RPC的研究。但是,RPC的完整實(shí)現(xiàn)比論文設(shè)計(jì)更少見(jiàn)。最近值得注意和關(guān)注的努力包括Courier在Xerox NS協(xié)議族中的研究和目前麻省理工學(xué)院的工作。
????????本文是為Cedar項(xiàng)目構(gòu)建RPC工具的結(jié)晶。我們感覺(jué)到,由于之前的工作(尤其是Nelson的論文和與之相關(guān)的研究),我們理解了一個(gè)RPC工具設(shè)計(jì)者必須做出的選擇。我們的任務(wù)是根據(jù)我們特定的目標(biāo)和環(huán)境做出選擇。事實(shí)上,我們發(fā)現(xiàn)有很多地方難以理解,我們制作了一個(gè)在某些方面有些新穎的系統(tǒng)。一個(gè)RPC工具設(shè)計(jì)者面對(duì)的主要問(wèn)題包括:當(dāng)發(fā)生機(jī)器故障和通信失敗時(shí)精確的調(diào)用語(yǔ)義;包含地址的參數(shù)在(可能)缺少共享地址空間時(shí)的語(yǔ)義;將遠(yuǎn)程調(diào)用集成到現(xiàn)有(或?qū)?lái))的編程系統(tǒng)中;綁定(調(diào)用者如何確定被調(diào)用者的位置和身份);適合調(diào)用者和被調(diào)用者之間傳輸控制和數(shù)據(jù)的協(xié)議;以及在一個(gè)開(kāi)放的通信網(wǎng)絡(luò)中,如何確保數(shù)據(jù)的完備性和安全性(如果需要的話)。在構(gòu)建我們的RPC包時(shí),我們解決了這些問(wèn)題,但是在一份簡(jiǎn)單的paper中以合適的深度描述所有這些問(wèn)題是不可能的。這篇paper包括我們關(guān)于這些問(wèn)題的討論和決策,以及我們對(duì)其解決方案的整體架構(gòu)。我們也描述了一些關(guān)于我們的綁定機(jī)制和傳輸層通信協(xié)議的細(xì)節(jié)。我們計(jì)劃在以后的論文中描述我們基于加密的安全設(shè)施,提供更多關(guān)于制作stub模塊(負(fù)責(zé)解釋RPC調(diào)用參數(shù)和結(jié)果)和我們實(shí)際使用該工具的經(jīng)驗(yàn)。
1.2 環(huán)境
????????我們構(gòu)建的遠(yuǎn)程過(guò)程調(diào)用包主要用于Cedar編程環(huán)境中,通過(guò)Xerox研究的內(nèi)部網(wǎng)絡(luò)進(jìn)行通信。在構(gòu)建這樣的包時(shí),環(huán)境的某些特征不可避免的會(huì)對(duì)設(shè)計(jì)造成影響,所以環(huán)境總結(jié)如下。
????????Cedar是一個(gè)專注于開(kāi)發(fā)功能強(qiáng)大且便于構(gòu)建的實(shí)驗(yàn)性編碼和系統(tǒng)環(huán)境的大型項(xiàng)目。這里強(qiáng)調(diào)的是它的統(tǒng)一性,高交互性的用戶接口,易于構(gòu)建和調(diào)試程序。Cedar的設(shè)計(jì)主要用于單用戶的工作環(huán)境,雖然它也用于服務(wù)器的構(gòu)建(共享電腦提供公共服務(wù),通過(guò)通信網(wǎng)絡(luò)訪問(wèn))。
????????使用Cedar最多的電腦是Dorados。Dorado是一個(gè)非常強(qiáng)大的機(jī)器(比如,一個(gè)簡(jiǎn)單的Algol風(fēng)格的調(diào)用返回花費(fèi)的時(shí)間小于10微秒)。它裝備了一個(gè)24bit的虛擬地址空間(16bit字符)和一個(gè)80MB的磁盤。對(duì)于單個(gè)用戶而言,可以將Dorado看成擁有像IBM370/168處理器能力的機(jī)器。
????????這些電腦之間的通信是很典型的每秒3MB的以太網(wǎng)(有一些電腦間能達(dá)到10MB每秒)。大多數(shù)運(yùn)行Cedar的電腦都在同一個(gè)以太網(wǎng)上,但是有一些是在我們的研究網(wǎng)絡(luò)中的不同的以太網(wǎng)上。互聯(lián)網(wǎng)絡(luò)包括大量3MB和10MB的以太網(wǎng)(目前大約160個(gè)),它們通過(guò)出租電話和衛(wèi)星鏈路連接。我們?cè)O(shè)想我們的RPC通信將遵循我們?cè)趧e的協(xié)議中見(jiàn)到過(guò)的模式:大多數(shù)通信都在本地以太網(wǎng)上(這樣對(duì)用戶來(lái)說(shuō),互聯(lián)網(wǎng)鏈路很低的數(shù)據(jù)速率就不會(huì)對(duì)用戶造成不方便),而且以太網(wǎng)也不會(huì)過(guò)載(我們幾乎沒(méi)有見(jiàn)過(guò)負(fù)載超過(guò)以太網(wǎng)承載容量的40%,最常見(jiàn)的是10%)。
????????PUP協(xié)議族提供了在互聯(lián)網(wǎng)間訪問(wèn)任何主機(jī)的統(tǒng)一的訪問(wèn)形式。先前的PUP協(xié)議包括簡(jiǎn)單不可靠(但是高概率)的數(shù)據(jù)報(bào)服務(wù)和簡(jiǎn)單可靠的流控制字節(jié)流。在統(tǒng)一以太網(wǎng)中的不同主機(jī)間,可以使用較低級(jí)別的以太網(wǎng)數(shù)據(jù)包格式。
????????基本上使用的所有編程語(yǔ)言都是高級(jí)語(yǔ)言,主要用的是Messa(根據(jù)Cedar進(jìn)行了修改),盡管也使用了Smalltalk和InterLisp。Dorados沒(méi)有匯編語(yǔ)言。
1.3 目標(biāo)
????????我們的RPC項(xiàng)目最主要的目的是使得分布式計(jì)算更容易。在我們之前的團(tuán)體研究中可以發(fā)現(xiàn),僅僅由一組選定的通信專家去保證通信系統(tǒng)的構(gòu)造是一項(xiàng)很困難的任務(wù)。甚至那些有大量深厚系統(tǒng)經(jīng)驗(yàn)的研究者也發(fā)現(xiàn),用已有的工具去獲取特定的用來(lái)構(gòu)造分布式系統(tǒng)的專業(yè)知識(shí)是一件很困難的事情。這是我們不希望看到的。我們擁有非常廣泛的,功能強(qiáng)大的通信網(wǎng)絡(luò),大量的性能強(qiáng)大的電腦,以及使得構(gòu)造程序相對(duì)容易的環(huán)境。現(xiàn)有的通信機(jī)制似乎成為了約束進(jìn)一步開(kāi)發(fā)分布式計(jì)算的主要因素。我們的愿景是通過(guò)提供幾乎和本地調(diào)用程序一樣簡(jiǎn)單輕松的通信機(jī)制,人們將因此被鼓舞去構(gòu)建并實(shí)驗(yàn)分布式的應(yīng)用。我們希望,RPC將消除構(gòu)造分布式系統(tǒng)的一切不必要的困難,只保留最基本的問(wèn)題:時(shí)序,組件間的故障獨(dú)立,獨(dú)立執(zhí)行環(huán)境的共存。
????????我們還有兩個(gè)希望能夠支持我們主要目標(biāo)的次要目標(biāo)。我們想要RPC通信盡可能的高效(比如說(shuō),超出網(wǎng)絡(luò)必要傳輸時(shí)間的5倍)。這似乎很重要,以免通信成本變得如此昂貴甚至讓應(yīng)用設(shè)計(jì)者極力想避免它。否則原本被開(kāi)發(fā)的應(yīng)用可能會(huì)因避免昂貴通信的渴望而導(dǎo)致扭曲。另外,我們發(fā)現(xiàn)讓RPC包的語(yǔ)義盡可能的強(qiáng)大時(shí)很重要的,而且不能丟失簡(jiǎn)潔性和有效性。否則,通過(guò)要求應(yīng)用程序員在RPC包之上構(gòu)建額外的機(jī)制,單個(gè)統(tǒng)一通信范式的收益將會(huì)丟失。在設(shè)計(jì)中的一個(gè)重要的問(wèn)題就是解決強(qiáng)大的語(yǔ)義和效率之間的矛盾。
????????我們最終最主要的目標(biāo)就是通過(guò)RPC提供安全的通信。以前實(shí)現(xiàn)的協(xié)議沒(méi)有任何保護(hù)我們?cè)诰W(wǎng)絡(luò)上傳輸數(shù)據(jù)的規(guī)范。這是真實(shí)的,即使密碼以明文傳輸。我們的信念是,對(duì)通過(guò)開(kāi)放網(wǎng)絡(luò)進(jìn)行安全通信的協(xié)議和機(jī)制的研究已經(jīng)到達(dá)一個(gè)階段——對(duì)我們而言把這種保護(hù)包含進(jìn)我們的包中是合理而且符合期望的。另外,幾乎沒(méi)有分布式系統(tǒng)已經(jīng)提供了安全的端到端通信,而且從來(lái)沒(méi)被運(yùn)用到RPC中,所以我們的設(shè)計(jì)將提供非常有用的研究見(jiàn)解。
1.4 基本設(shè)計(jì)
????????我們應(yīng)該使用程序調(diào)用作為一種表達(dá)控制和數(shù)據(jù)傳輸?shù)姆妒健@不是我們目標(biāo)的直接結(jié)果。例如,消息傳遞是一種似是而非的選擇。我們相信在這些可替代方案中做出選擇不會(huì)對(duì)這種設(shè)計(jì)所面臨的問(wèn)題以及被采用的解決方案產(chǎn)生重大影響??煽亢陀行鬏斠约捌淇赡艿幕貜?fù)的問(wèn)題和遠(yuǎn)程過(guò)程調(diào)用遇到的問(wèn)題非常類似。傳輸參數(shù)和結(jié)果以及網(wǎng)絡(luò)安全的問(wèn)題本質(zhì)上沒(méi)變。使得我們選擇遠(yuǎn)程過(guò)程調(diào)用的最重要的考慮是它們是嵌入在我們的主要的編程語(yǔ)言Mesa中的主要的控制和數(shù)據(jù)傳輸機(jī)制。
????????人們也可能考慮使用一種更加并行的模式來(lái)進(jìn)行通信,比如某種形式的遠(yuǎn)程分支。因?yàn)槲覀兊恼Z(yǔ)言已經(jīng)包含了用于分支并行計(jì)算的構(gòu)造,我們本可以選擇這個(gè)作為添加通信語(yǔ)義的點(diǎn)。同樣,這并不會(huì)改變主要的設(shè)計(jì)問(wèn)題。
????????我們放棄了在電腦之間模擬某種共享地址的可能性。以前的工作已經(jīng)表明,在充分注意的情況下,可以通過(guò)這種方式達(dá)到中等效率。我們不知道采用共享地址的方法是否可行,但是兩個(gè)潛在的主要困難已經(jīng)浮現(xiàn)在腦海:首先,遠(yuǎn)程地址的表示是否可以集成到我們的編程語(yǔ)言(可能還有底層的機(jī)器架構(gòu))中而不會(huì)導(dǎo)致劇烈的動(dòng)蕩;其次,效率是否可以接受。例如,在PUP網(wǎng)絡(luò)中的主機(jī)被一個(gè)16位的地址表示,所以一個(gè)簡(jiǎn)單的共享地址空間的實(shí)現(xiàn)將會(huì)把語(yǔ)言地址空間的寬度擴(kuò)展16位。另一方面,小心地使用我們的虛擬內(nèi)存硬件的地址映射機(jī)制可以允許共享地址空間而無(wú)需改變地址寬度。即使在我們的10MB以太網(wǎng)上,數(shù)據(jù)包交換最小的平均往返時(shí)間也是120微妙。因此最有可能實(shí)現(xiàn)這個(gè)的方式就是去使用某種傳呼系統(tǒng)。總之,在RPC參與者間的共享地址空間可能是可行的,但是因?yàn)槲覀儧](méi)有意愿去進(jìn)行該項(xiàng)研究,因此我們隨后的設(shè)計(jì)中假設(shè)沒(méi)有共享空間。我們的直覺(jué)是,在我們的硬件設(shè)備上,使用共享地址空間花費(fèi)的代價(jià)要超出使用它帶來(lái)的益處。
????????在做設(shè)計(jì)選擇的時(shí)候我們多次用到的一個(gè)原則就是遠(yuǎn)程過(guò)程調(diào)用的語(yǔ)義要盡可能地接近那些本地(單機(jī))過(guò)程調(diào)用的語(yǔ)義。作為一種保證RPC工具易用性的方式,這個(gè)原則似乎非常有吸引力,尤其對(duì)于那些熟悉使用單機(jī)語(yǔ)言和語(yǔ)言包的程序員而言。違反這個(gè)原則似乎可能會(huì)把我們引向一種困境,即使得從前的通信包和協(xié)議變得難以使用。這個(gè)原則可能偶爾會(huì)導(dǎo)致我們偏離那種對(duì)有豐富分布式計(jì)算經(jīng)驗(yàn)的人而言很有吸引力的設(shè)計(jì)。比如說(shuō),我們沒(méi)有設(shè)計(jì)超時(shí)機(jī)制來(lái)限制遠(yuǎn)程調(diào)用持續(xù)的時(shí)間(在沒(méi)有機(jī)器和通信故障的情況下),然而大多數(shù)通信包認(rèn)為認(rèn)為這是一個(gè)有價(jià)值的功能。我們的觀點(diǎn)是本地過(guò)程調(diào)用沒(méi)有超時(shí)機(jī)制,而且我們的語(yǔ)言包含了一種機(jī)制能夠去終止那種作為并行處理的一部分的活動(dòng)。僅僅為RPC設(shè)計(jì)一個(gè)超時(shí)管理機(jī)制將毫無(wú)必要地將程序員的世界變得更復(fù)雜。同樣地,我們選擇了下面描述的構(gòu)造語(yǔ)義(基于現(xiàn)有的Cedar機(jī)制)而不是在Nelson的論文中提出的那些。
1.5 結(jié)構(gòu)

????????我們用于RPC的程序結(jié)構(gòu)和Nelson的論文中提出的類似。它基于stub的概念。當(dāng)發(fā)起遠(yuǎn)程調(diào)用時(shí),涉及到五部分程序:user,user-stub,RPC通信包(稱為RPCRuntime),setver-stub,server。它們的關(guān)系如圖一所示。user,user-stub和其中一個(gè)RPCRuntime的實(shí)例在調(diào)用者機(jī)器上執(zhí)行;server,server-stub和另外一個(gè)RPCRuntime實(shí)例在被調(diào)用者機(jī)器上執(zhí)行。當(dāng)使用者希望去發(fā)起一個(gè)遠(yuǎn)程調(diào)用時(shí),它其實(shí)是執(zhí)行了一個(gè)完全正常的本地調(diào)用,而這個(gè)調(diào)用會(huì)去調(diào)用user-stub中相應(yīng)的程序。user-stub負(fù)責(zé)將目標(biāo)程序的規(guī)范和參數(shù)放置在一個(gè)或多個(gè)包中,并請(qǐng)求RPCRuntime將這些包可靠地傳輸給被調(diào)用者機(jī)器。一旦接收到這些包,被調(diào)用者機(jī)器上的RPCRuntime就把它們傳送給server-stub。Server-stub將它們解包,像是執(zhí)行一個(gè)完全正常的本地調(diào)用一樣,該本地調(diào)用會(huì)調(diào)用server中相對(duì)應(yīng)的程序。與此同時(shí),調(diào)用者機(jī)器上的調(diào)用進(jìn)程將被掛起并等待結(jié)果包的返回。當(dāng)server中的調(diào)用完成時(shí),它將結(jié)果返回給server-stub打包,然后結(jié)果包將被傳送回給調(diào)用者機(jī)器上掛起的進(jìn)程。它們將被user-stub解包并返回給user。RCPCRuntime負(fù)責(zé)重傳,確認(rèn),數(shù)據(jù)包路由和加密。除去多機(jī)器間機(jī)器綁定或者通信失敗的影響,調(diào)用就仿佛user直接在server上調(diào)用程序一樣。確實(shí)是這樣,如果user和server的代碼被放在一個(gè)機(jī)器上,并被直接綁定在一起(而無(wú)需stub),程序?qū)⑷阅芄ぷ鳌?/p>
????????RPCRuntime是Cedar系統(tǒng)的標(biāo)準(zhǔn)部分。User和Server是需要作為分布式應(yīng)用的一部分被編寫的。但是user-stub和server-stub卻是被一個(gè)叫Lupine的程序自動(dòng)生成的。這個(gè)生成是通過(guò)使用Mesa接口模塊指定的。這些是Mesa(和Cedar)分別編譯和綁定機(jī)制的基礎(chǔ)。接口模塊最主要是一系列程序的名稱,以及它們的參數(shù)類型和結(jié)果。對(duì)于調(diào)用者和被調(diào)用者來(lái)說(shuō),這已經(jīng)提供了足夠的信息以供它們獨(dú)立地執(zhí)行編譯時(shí)的類型檢查并生成合適的調(diào)用序列。實(shí)現(xiàn)了接口過(guò)程的程序模塊被稱為導(dǎo)出接口。調(diào)用接口過(guò)程的程序模塊被稱為導(dǎo)入接口。當(dāng)一個(gè)程序員想要編寫一個(gè)分布式應(yīng)用時(shí),他首先應(yīng)該編寫一組接口模塊。然后再去編寫導(dǎo)入該接口的user code和導(dǎo)出該接口的server code。他也應(yīng)該將該接口暴露給Lupine,Lupine將生成user-stub(導(dǎo)出接口)和server-stub(導(dǎo)入接口)。當(dāng)把程序綁定到調(diào)用者機(jī)器上時(shí),user即被綁定到user-stub。在被調(diào)用者機(jī)器上,server-stub也與server綁定。
????????因此,程序員不需要去詳細(xì)地構(gòu)建那些與通信相關(guān)的細(xì)節(jié)代碼。在設(shè)計(jì)好接口后,只需要去編寫user code和server code即可。Lupine負(fù)責(zé)生成打包和解包參數(shù)以及結(jié)果(還有別的關(guān)于參數(shù)和結(jié)果語(yǔ)義的細(xì)節(jié))的代碼,以及為server-stub中接收到的請(qǐng)求調(diào)度正確的程序。程序員必須避免指定與缺少共享地址空間不兼容的參數(shù)和結(jié)果(Lupine將做這種檢查)。程序員還必須采取措施去調(diào)用第2部分描述的intermachine綁定,還要去處理被報(bào)告的機(jī)器和通信故障。
2 綁定
????????我們依次考慮綁定的兩個(gè)方面。首先,一個(gè)綁定機(jī)制的客戶端如何指定他被綁定的綁定機(jī)制?其次,調(diào)用者如何確定被調(diào)用者機(jī)器的地址并指定被調(diào)用者調(diào)用哪些程序(過(guò)程)?第一個(gè)主要是命名的問(wèn)題,第二個(gè)是定位的問(wèn)題。
2.1 命名
????????由我們的RPC包提供的綁定操作是將一個(gè)接口的導(dǎo)入器綁定到接口的導(dǎo)出器。綁定之后,導(dǎo)入器發(fā)出的調(diào)用將會(huì)調(diào)用被(遠(yuǎn)程)導(dǎo)出器實(shí)現(xiàn)的過(guò)程。接口名稱分為兩部分:類型和實(shí)例。類型是在某種抽象的層次上指定調(diào)用者期望被調(diào)用者去實(shí)現(xiàn)哪個(gè)接口。實(shí)例是指定所需抽象接口的特定實(shí)現(xiàn)。比如,接口的類型可能對(duì)應(yīng)于“郵件服務(wù)器”的抽象,實(shí)例可能對(duì)應(yīng)于從很多郵箱服務(wù)器中選出的一些特定的服務(wù)器。接口類型的合理默認(rèn)值可能是一個(gè)從Mesa接口模塊派生出的名字。從根本上說(shuō),一個(gè)接口名字的語(yǔ)義不是由RPC包所決定的——它們是導(dǎo)出器和導(dǎo)入器之間的協(xié)定,并不是RPC包可完全強(qiáng)制的。然而,導(dǎo)出器使用接口名稱去定位導(dǎo)出器卻是由RPC包指定的,我們現(xiàn)在將描述它。
2.2 定位合適的導(dǎo)出器
????????我們使用Grapevine分布式數(shù)據(jù)庫(kù)進(jìn)行RPC綁定。使用Grapevine的主要吸引力是它的廣泛性和可靠性。Grapevine策略性地分布于位于我們網(wǎng)絡(luò)拓補(bǔ)中的多臺(tái)服務(wù)器上,而且它被配置去保存至少三個(gè)數(shù)據(jù)庫(kù)entry的副本。由于Grapevine服務(wù)本身就極其可靠而且數(shù)據(jù)有多個(gè)副本,我們幾乎不會(huì)遇到丟失數(shù)據(jù)entry的情況。有使用這種數(shù)據(jù)庫(kù)的替代方案,但它們并不能令我們滿意。比如,我們可以以它們希望的方式在我們應(yīng)用的程序中包含將要與之進(jìn)行通信的機(jī)器的網(wǎng)絡(luò)地址:對(duì)于大多數(shù)應(yīng)用來(lái)說(shuō),這將會(huì)過(guò)早地綁定一個(gè)特定的機(jī)器。除此以外,我們可以使用某種廣播協(xié)議去定位期望的機(jī)器:通常這是可以接受的,但是作為一種籠統(tǒng)性的機(jī)制將會(huì)對(duì)無(wú)辜的旁觀者造成太多干擾,而且綁定到那些非本地的網(wǎng)絡(luò)中的機(jī)器時(shí)也不夠方便。
????????Grapevine的數(shù)據(jù)庫(kù)由一系列的entry組成,每一個(gè)entry都對(duì)應(yīng)一個(gè)被稱為Rname的鍵。Entries有兩種:individuals(單個(gè)的)和groups(分組的)。Grapevine對(duì)每一個(gè)數(shù)據(jù)庫(kù)entry都維持了很多元信息,但是RPC包只關(guān)心兩個(gè):對(duì)于每一個(gè)individual來(lái)說(shuō)都有一個(gè)連接地址——這個(gè)地址是一個(gè)網(wǎng)絡(luò)地址,對(duì)于每一個(gè)group來(lái)說(shuō)則有一個(gè)成員列表——是一系列的Rname。RPC包在Grapevine數(shù)據(jù)庫(kù)中為每個(gè)接口名稱維持兩個(gè)entries:每個(gè)類型一個(gè),每個(gè)實(shí)例一個(gè);所以類型和實(shí)例都是Grapevine Rnames。實(shí)例的數(shù)據(jù)庫(kù)entry是一個(gè)Grapevine individual,它的連接地址是一個(gè)網(wǎng)絡(luò)地址,具體來(lái)說(shuō)就是那個(gè)實(shí)例最后被導(dǎo)出到的機(jī)器的網(wǎng)絡(luò)地址。類型的數(shù)據(jù)庫(kù)entry是一個(gè)Grapevine group,它的成員是那些已被導(dǎo)出的類型的實(shí)例的Grapevine Rnames。例如,如果一個(gè)運(yùn)行在網(wǎng)絡(luò)地址為3#22#的服務(wù)導(dǎo)出了一個(gè)類型為FileAccess.Alpine實(shí)例為Ebbets.Alpine的遠(yuǎn)程接口,而一個(gè)運(yùn)行在網(wǎng)絡(luò)地址為3#276#上的服務(wù)導(dǎo)出了一個(gè)類型為FileAccess.Alpine實(shí)例為L(zhǎng)uther.Alpine的遠(yuǎn)程接口,那么Grapevine group FileAccess.Alpine將包括兩個(gè)成員:Ebbets.Alpine和Luther.Alpine。The Grapevine individual Ebbets. Alpine將把3#22#作為它的連接地址,Luther.Alpine的連接地址則為3#276#。
????????當(dāng)希望將一個(gè)導(dǎo)出器的接口對(duì)遠(yuǎn)程客戶端可見(jiàn)時(shí),服務(wù)端代碼將調(diào)用server-stub,隨之server-stub將調(diào)用RPCRuntime中的一個(gè)過(guò)程,即導(dǎo)出接口。導(dǎo)出接口被賦予接口名稱(類型和實(shí)例)和一個(gè)過(guò)程(被稱為調(diào)度器),該調(diào)度器在server-stub中實(shí)現(xiàn),用來(lái)處理接口的傳入調(diào)用。導(dǎo)出接口調(diào)用Grapvine并確保該實(shí)例是Grapevine group(該類型)的成員之一,以及該實(shí)例的連接地址是導(dǎo)出機(jī)器的網(wǎng)絡(luò)地址。這可能導(dǎo)致更新數(shù)據(jù)庫(kù)。一種優(yōu)化是如果它包含了正確的信息,那么數(shù)據(jù)庫(kù)將不會(huì)被更新——這通常是正確的:尤其當(dāng)來(lái)自同一網(wǎng)絡(luò)地址的同一接口已被導(dǎo)出的情況。例如,為了從網(wǎng)絡(luò)地址3#22#導(dǎo)出類型為FileAccess.Alpine和實(shí)例為Ebbets.Alpine的接口,RPCRuntime將確保在Grapevine數(shù)據(jù)庫(kù)中的Ebbets.Alpine含有連接地址為3#22#的信息,以及Ebbets.Alpine是FileAccess.Alpine的成員之一。隨后,RPCRuntime在位于導(dǎo)出的機(jī)器上的一張表中記錄關(guān)于這個(gè)導(dǎo)出的信息,對(duì)每個(gè)當(dāng)前被導(dǎo)出的接口而言,這張表包含了接口名稱,server-stub中的調(diào)度過(guò)程,以及一個(gè)永久的獨(dú)一無(wú)二的用于標(biāo)識(shí)這個(gè)導(dǎo)出的32位的值。該表是一個(gè)由小整數(shù)索引的數(shù)組實(shí)現(xiàn)的。通過(guò)使用32位計(jì)數(shù)器的連續(xù)值,保證標(biāo)識(shí)符的永久唯一性;在啟動(dòng)時(shí),這個(gè)計(jì)數(shù)器初始化為值是一秒的實(shí)時(shí)時(shí)鐘,隨后該計(jì)數(shù)器被約束為小于當(dāng)前這個(gè)時(shí)鐘的值。這種限制使得對(duì)單機(jī)上導(dǎo)出接口的調(diào)用速率平均小于每秒1次,這是自導(dǎo)出機(jī)器重啟以來(lái)的平均值。這種調(diào)用的突發(fā)速率可以超過(guò)每秒一次(見(jiàn)圖2)。

????????當(dāng)一個(gè)導(dǎo)入器希望綁定到一個(gè)導(dǎo)出器時(shí),user code會(huì)調(diào)用它的uset-stub,隨后user-stub會(huì)調(diào)用RPCRuntime中的一個(gè)過(guò)程,即導(dǎo)入接口,為其提供所需的接口類型和實(shí)例。
????????RPCRuntime通過(guò)向Grapevine請(qǐng)求網(wǎng)絡(luò)地址(即接口實(shí)例的連接地址)來(lái)確定的導(dǎo)出器(如果有的話)的網(wǎng)絡(luò)地址。隨后,RPCRuntime將發(fā)起一個(gè)遠(yuǎn)程調(diào)用去請(qǐng)求遠(yuǎn)程機(jī)器上的RPCRuntime包以獲取有關(guān)該接口的類型和實(shí)例的綁定信息。如果指定的機(jī)器當(dāng)前未能導(dǎo)出那個(gè)接口,該事實(shí)將被返回給導(dǎo)入機(jī)器,則綁定失敗。如果被指定的機(jī)器當(dāng)前正導(dǎo)出該接口,則其RPCRuntime維護(hù)的當(dāng)前導(dǎo)出表將生成相應(yīng)的唯一標(biāo)識(shí)符;該標(biāo)識(shí)符和該表的索引將會(huì)被返回給導(dǎo)入機(jī)器,綁定成功。導(dǎo)出器的網(wǎng)絡(luò)地址,唯一標(biāo)識(shí)符和表索引將被user-stub記住并在遠(yuǎn)程調(diào)用時(shí)使用。
????????接下來(lái),當(dāng)該user-stub在導(dǎo)入的遠(yuǎn)程接口上發(fā)起調(diào)用時(shí),它產(chǎn)生的調(diào)用包包含了所需接口的唯一標(biāo)識(shí)符和表索引,以及該接口所需過(guò)程的entry point編號(hào)。當(dāng)在被調(diào)用者機(jī)器上的RPCRuntime接收到這個(gè)調(diào)用包時(shí),它將使用該包中的索引去搜尋該當(dāng)前導(dǎo)出表(很快),并驗(yàn)證包中的唯一標(biāo)識(shí)符與表中的唯一標(biāo)識(shí)符是否一致,然后將該調(diào)用包傳遞給包中指定的調(diào)度過(guò)程。
????????我們的客戶可以使用這種綁定方案的幾種變體。如果調(diào)用導(dǎo)入接口的導(dǎo)入器僅僅指定了接口類型卻沒(méi)指定實(shí)例,RPCRuntime將從Grapevine獲得由該類型命名的Grapevine group成員。RPCRuntime隨后獲取到該組中的每個(gè)成員的網(wǎng)絡(luò)地址,并依次嘗試這些地址以找到那些將接收綁定請(qǐng)求的實(shí)例:這很快就會(huì)被完成,以一種趨向于定位最近的(相應(yīng)最快的)正在運(yùn)行的導(dǎo)出器的順序。這允許導(dǎo)入器綁定到最靠近的運(yùn)行中的服務(wù)副本的實(shí)例,但是導(dǎo)入器并不關(guān)心是哪個(gè)實(shí)例。當(dāng)然,導(dǎo)入器可以通過(guò)枚舉由該類型命名的組的成員來(lái)自由枚舉實(shí)例。
????????實(shí)例可能是網(wǎng)絡(luò)地址常量而不是一個(gè)Grapevine名稱。這將允許導(dǎo)入器綁定到導(dǎo)出器而不與Grapevine進(jìn)行任何交互,代價(jià)就是在應(yīng)用程序中要包含一個(gè)明確的網(wǎng)絡(luò)地址。
2.3 討論
????????這個(gè)方案由一些重要的作用。請(qǐng)注意,導(dǎo)入一個(gè)接口對(duì)導(dǎo)出機(jī)器中的數(shù)據(jù)結(jié)構(gòu)沒(méi)有影響;這對(duì)于構(gòu)建有大量用戶的服務(wù)而言是有利的,而且避免了服務(wù)器如何處理隨后導(dǎo)入接口崩潰相關(guān)信息的問(wèn)題。此外,使用唯一標(biāo)識(shí)符的方案意味著如果導(dǎo)出器崩潰和重啟(因?yàn)槲ㄒ粯?biāo)識(shí)符在每次調(diào)用時(shí)都要被檢查),綁定將被隱式破壞。我們相信這種隱式地解除綁定是一種正確的語(yǔ)義:否則當(dāng)調(diào)用失敗時(shí)將不會(huì)通知用戶。最后值得注意的是此種方案只允許調(diào)用通過(guò)RPC機(jī)制顯示導(dǎo)出的過(guò)程。另一種更有效的方案是使用導(dǎo)出器的server-stub調(diào)度程序的內(nèi)部表示來(lái)發(fā)布導(dǎo)入器;我們認(rèn)為這種做法并不是我們期望的,因?yàn)樗鼘⒃试S對(duì)服務(wù)端機(jī)器的任何程序進(jìn)行未經(jīng)檢查的訪問(wèn),因此,將無(wú)法強(qiáng)制進(jìn)行任何保護(hù)或者安全方案。
????????限制對(duì)更新Grapevine數(shù)據(jù)庫(kù)的訪問(wèn)控制能夠限制那些將要導(dǎo)出特定接口名稱的用戶。這些是期望的語(yǔ)義:比如,對(duì)一個(gè)隨機(jī)用戶而言,他聲稱他的工作站是一個(gè)郵件服務(wù)器從而想去攔截我的消息流量,這是不可能的。對(duì)服務(wù)的副本而言,這種訪問(wèn)控制也至關(guān)重要。服務(wù)副本的客戶端可能不會(huì)事先知道服務(wù)實(shí)例的名稱。如果客戶端希望使用雙向驗(yàn)證來(lái)確保服務(wù)是真實(shí)的,并且如果我們希望避免使用幾個(gè)簡(jiǎn)單的密碼來(lái)作為每個(gè)服務(wù)實(shí)例的驗(yàn)證,那么客戶端必須能夠安全地獲取服務(wù)實(shí)例的名稱列表。在客戶端與Grapevine交互的過(guò)程中,當(dāng)接口被導(dǎo)入時(shí),我們可以采用一種安全協(xié)議來(lái)實(shí)現(xiàn)這種安全機(jī)制。因此,Grapevine的訪問(wèn)控制能夠使客戶端確保服務(wù)實(shí)例是真實(shí)的(經(jīng)授權(quán)的)。
????????我們?cè)试S多種事件綁定選擇。最靈活的選擇是導(dǎo)入器僅僅指定接口的類型而不用指定其實(shí)例:此處關(guān)于接口的實(shí)例是動(dòng)態(tài)決定的。接下來(lái)(最常見(jiàn)的)接口實(shí)例是Rname,它將延遲特定導(dǎo)出機(jī)器的選擇。最具限制性的功能是將一個(gè)網(wǎng)絡(luò)地址指定為一個(gè)實(shí)例,從而在編譯時(shí)將其綁定到一個(gè)特定的機(jī)器上。我們也提供允許導(dǎo)入器動(dòng)態(tài)實(shí)例化接口并導(dǎo)入它們的工具。關(guān)于如何實(shí)現(xiàn)此操作的詳細(xì)說(shuō)明對(duì)于本文而言太過(guò)復(fù)雜,但是總的來(lái)說(shuō),它允許導(dǎo)入器將其程序綁定到多個(gè)導(dǎo)出機(jī)器,即使導(dǎo)入器也無(wú)法靜態(tài)的知道它希望綁定多少臺(tái)機(jī)器。事實(shí)證明,這在一些開(kāi)放式的多機(jī)算法中非常有用,例如分布式原子事物管理器的實(shí)現(xiàn)。我們不允許以比整個(gè)接口更細(xì)的粒度進(jìn)行綁定。考慮到我們?cè)诎拖到y(tǒng)中已經(jīng)觀察到的這種機(jī)制的不可用性,這不是我們考慮的選擇。
3 包層級(jí)傳輸協(xié)議
3.1 要求
????????其實(shí)不必設(shè)計(jì)一個(gè)特定的包層協(xié)議就可以實(shí)現(xiàn)RPC的語(yǔ)義。比如,我們本可以通過(guò)使用PUP字節(jié)流協(xié)議(或者Xerox NS序列化包協(xié)議)作為傳輸層的協(xié)議來(lái)構(gòu)建我們的包。我們以前的一些實(shí)驗(yàn)就使用了PUP字節(jié)流, Xerox NS "Courier" RPC協(xié)議使用了NS序列化包協(xié)議。Grapevine協(xié)議本質(zhì)上類似于使用PUP字節(jié)流的遠(yuǎn)程過(guò)程調(diào)用。我們的測(cè)量以及每個(gè)實(shí)施的經(jīng)驗(yàn)使我們確信這種方法并不能令人滿意。RPC通信的特性意味著如果設(shè)計(jì)并實(shí)現(xiàn)一個(gè)專門用于RPC的協(xié)議將會(huì)在性能上有極大的提升。我們的實(shí)驗(yàn)表明,性能增益可能達(dá)到10倍。
????????一種中間的站位可能是成立的:我們從來(lái)沒(méi)有嘗試過(guò)使用現(xiàn)存?zhèn)鬏攲訁f(xié)議構(gòu)建一個(gè)傳輸協(xié)議的實(shí)現(xiàn)以專用于RPC。然而,RPC通信的性質(zhì)完全不同于通常采用字節(jié)流的大數(shù)據(jù)傳輸,我們認(rèn)為這個(gè)中間位置是不可行的。
????????我們?cè)趨f(xié)議中強(qiáng)調(diào)的目標(biāo)是最小化在啟動(dòng)調(diào)用和獲得結(jié)果之間經(jīng)過(guò)的時(shí)間。讓協(xié)議用于大批量數(shù)據(jù)傳輸這并不重要:絕大多數(shù)的時(shí)間其實(shí)是花在了傳輸數(shù)據(jù)上。我們還努力減小用戶量很大時(shí)加給服務(wù)器的負(fù)擔(dān)。當(dāng)執(zhí)行大批量數(shù)據(jù)傳輸時(shí),采用花費(fèi)大量成本在建立和斷開(kāi)連接上是可以接受的,而且這要求維護(hù)一個(gè)連接中大量的狀態(tài)信息。這些都是可以接受的因?yàn)橄鄬?duì)于數(shù)據(jù)傳輸本身而言,成本是極小的。我們相信這對(duì)于RPC來(lái)說(shuō)是不合適的。我們?cè)O(shè)想我們的機(jī)器可以服務(wù)大量的用戶,要求大量的狀態(tài)信息或者昂貴的連接握手是不可接收的。
????????正是這個(gè)RPC包級(jí)別定義了語(yǔ)義和我們?yōu)檎{(diào)用提供的保證。我們保證如果調(diào)用返回給了用戶,隨后在服務(wù)端的過(guò)程就被精確地調(diào)用了一次。否則,發(fā)生的異常將被告知用戶,而過(guò)程則被調(diào)用了一次或者根本沒(méi)有被調(diào)用——用戶不會(huì)被告知是哪種情況。如果發(fā)生了異常,用戶不知道是服務(wù)端崩潰了還是通信網(wǎng)絡(luò)出了問(wèn)題。如果服務(wù)器端的機(jī)器上的RPCRuntime仍在響應(yīng),我們等待結(jié)果的時(shí)間將沒(méi)有上限;那就是說(shuō),如果有通信故障或崩潰,我們將廢棄調(diào)用,而如果服務(wù)端代碼出現(xiàn)了死鎖或者無(wú)限循環(huán)則不會(huì)廢棄調(diào)用。這和本地過(guò)程調(diào)用的語(yǔ)義完全相同。
3.2 簡(jiǎn)單調(diào)用
????????我們?cè)噲D使每個(gè)通信調(diào)用都做到特別高效,因?yàn)樵谒袇?shù)和結(jié)果都適用一個(gè)簡(jiǎn)單的包緩沖區(qū)以及頻繁調(diào)用會(huì)發(fā)生的情況都是如此。發(fā)起調(diào)用時(shí),調(diào)用者發(fā)送一個(gè)包含調(diào)用標(biāo)識(shí)符(下面會(huì)討論),指定所需過(guò)程(正如綁定連接中描述)的數(shù)據(jù),以及參數(shù)。當(dāng)被調(diào)用者接收到該包時(shí)相對(duì)應(yīng)的過(guò)程將被調(diào)用。當(dāng)過(guò)程返回時(shí),一個(gè)包含了同樣調(diào)用標(biāo)識(shí)符的結(jié)果包,即結(jié)果,將會(huì)被返回給調(diào)用者。
????????為了補(bǔ)齊可能丟失的包,發(fā)送包的機(jī)器負(fù)責(zé)重傳直到它收到確認(rèn)已經(jīng)接收到包。然而,調(diào)用結(jié)果足以確認(rèn)調(diào)用包已經(jīng)被接收,而且調(diào)用包也足以確認(rèn)給進(jìn)程先前調(diào)用的結(jié)果包。因此,在調(diào)用持續(xù)時(shí)間和調(diào)用間隔均小于傳輸間隔的情況下,我們?cè)诿看握{(diào)用中精確地傳輸了兩個(gè)包(每個(gè)方向一個(gè))。如果調(diào)用持續(xù)的時(shí)間較長(zhǎng)或者調(diào)用間隔較長(zhǎng),甚至達(dá)到了再發(fā)送另外兩個(gè)包(重傳或顯示的確認(rèn)包)的時(shí)間;我們?nèi)匀徽J(rèn)為這個(gè)是可以接受的,因?yàn)樵谶@種情況下,很明顯通信時(shí)間花費(fèi)不再是性能的限制因素。
????????調(diào)用標(biāo)識(shí)符主要為兩個(gè)目的服務(wù)。它能夠讓調(diào)用者確定結(jié)果包確實(shí)是它當(dāng)前調(diào)用的結(jié)果(例如,不是以前的某個(gè)調(diào)用延遲的結(jié)果),另外,它允許被調(diào)用者清除重復(fù)的調(diào)用包(例如,由重傳造成的)。調(diào)用標(biāo)識(shí)符由調(diào)用機(jī)器標(biāo)識(shí)符(這個(gè)是永久的也是全局唯一的),一個(gè)機(jī)器相關(guān)的進(jìn)程標(biāo)識(shí)符,以及一個(gè)序列數(shù)字組成。我們?cè)趯W(xué)術(shù)上將【機(jī)器標(biāo)識(shí)符,進(jìn)程】稱為一個(gè)activity。Activity的一個(gè)重要屬性是在任何時(shí)刻每個(gè)activity最多只能由一個(gè)活躍的遠(yuǎn)程調(diào)用——在它接收到前一個(gè)調(diào)用結(jié)果之前,他將不會(huì)再初始化任何新的調(diào)用。每個(gè)activity的調(diào)用序列數(shù)字必須是不變的(但不是必須有順序)。被調(diào)用者機(jī)器上的RPCRuntime維護(hù)著一張表,這張表提供了每個(gè)活躍activity最近一次調(diào)用的序列數(shù)字。當(dāng)調(diào)用包被接收時(shí),就從這張表中查找它的調(diào)用標(biāo)識(shí)符。這個(gè)調(diào)用包可能會(huì)被當(dāng)做副本丟棄(很可能是在確認(rèn)后)除非它的序列數(shù)字比在這張表中查到的大。圖3展示了在一個(gè)簡(jiǎn)單的調(diào)用中包的傳輸過(guò)程。

????????將這種安排和在更重量級(jí)的傳輸協(xié)中建立連接,維護(hù)和中止進(jìn)行比較很有趣。在我們的協(xié)議中,我們認(rèn)為連接就是調(diào)用者機(jī)器上的activity和服務(wù)端機(jī)器上的RPCRtime包接收來(lái)自該activity共享狀態(tài)信息的過(guò)程。我們不要求特定的建立連接協(xié)議(相比于其他協(xié)議所要求的雙包握手而言);接收到先前未知的activity的包已足夠去隱式地創(chuàng)建連接。當(dāng)連接處于激活狀態(tài)(有調(diào)用正在被處理,或者該調(diào)用的最后一個(gè)結(jié)果包還沒(méi)有被確認(rèn)),兩端都維持著大量的狀態(tài)信息。然而,當(dāng)連接處于空閑狀態(tài)時(shí),服務(wù)器上的唯一狀態(tài)信息是它的序列號(hào)表中的條目。當(dāng)連接處于空閑狀態(tài)時(shí),調(diào)用者會(huì)最小化狀態(tài)信息:僅夠一臺(tái)機(jī)器計(jì)數(shù)就足夠了。當(dāng)初始化一個(gè)新的調(diào)用,它的序列號(hào)就是這個(gè)計(jì)數(shù)器的下一個(gè)值。這就是來(lái)自一個(gè)activity的調(diào)用的序列號(hào)僅僅被要求是不變的,而不是有序的原因。當(dāng)一個(gè)連接處于空閑狀態(tài)時(shí),任一一臺(tái)機(jī)器中的進(jìn)程都與該連接無(wú)關(guān)。不要求通信(比如“pinging”包交換)去維護(hù)空閑連接。我們沒(méi)有明確的連接終端協(xié)議。如果一個(gè)連接處于空閑狀態(tài),服務(wù)器就會(huì)在一定的時(shí)間間隔后丟棄該空閑連接的狀態(tài)信息,此時(shí)不再有任何接收重傳調(diào)用包的危險(xiǎn)(例如,五分鐘后),而且它可以無(wú)需告知調(diào)用者機(jī)器就這么做。這種方案無(wú)需成本即可保證傳統(tǒng)的面向連接協(xié)議。但盡管如此,在遠(yuǎn)程綁定時(shí)我們依賴于介紹過(guò)的唯一標(biāo)識(shí)符。如果服務(wù)發(fā)生崩潰然后重啟,而這時(shí)調(diào)用者仍然在重傳一個(gè)調(diào)用包(雖不太可能,但也合理),沒(méi)有標(biāo)識(shí)符的話我們將無(wú)法判斷重復(fù)數(shù)據(jù)。我們也假設(shè)即使調(diào)用者機(jī)器重啟,來(lái)自同一個(gè)activity的調(diào)用序列號(hào)也不能重復(fù)(否則這個(gè)來(lái)自于重啟機(jī)器的調(diào)用可能會(huì)被當(dāng)做副本刪除)。事實(shí)上,我們認(rèn)為這個(gè)是32位會(huì)話標(biāo)識(shí)符的副作用,我們將其與安全調(diào)用一起使用。對(duì)于非安全調(diào)用,會(huì)話標(biāo)識(shí)符可以被看作是區(qū)分調(diào)用機(jī)器的永久唯一標(biāo)識(shí)符。在每次調(diào)用中,會(huì)話標(biāo)識(shí)符都會(huì)同調(diào)用序列號(hào)一起被傳輸。我們基于每個(gè)機(jī)器維護(hù)的32位時(shí)鐘生成會(huì)話標(biāo)識(shí)符(當(dāng)機(jī)器重啟時(shí),從網(wǎng)絡(luò)時(shí)間服務(wù)器初始化)。
????????根據(jù)以前的系統(tǒng)經(jīng)驗(yàn),我們預(yù)計(jì)這種輕量級(jí)的連接管理在構(gòu)建大型繁忙的分布式中將會(huì)非常重要。
3.3 復(fù)雜調(diào)用
????????如上所述,包傳輸器負(fù)責(zé)重傳包直到它被確認(rèn)。在這樣做的過(guò)程中,包被修改以請(qǐng)求一個(gè)顯示的確認(rèn)。這將處理丟失包,持續(xù)時(shí)間長(zhǎng)的調(diào)用,和調(diào)用間的長(zhǎng)時(shí)間間隔。當(dāng)調(diào)用者對(duì)確認(rèn)感到滿意時(shí),調(diào)用進(jìn)程將等待結(jié)果包。然而在等待過(guò)程中,調(diào)用者會(huì)周期性地發(fā)送探測(cè)包給被調(diào)用者,而這是被調(diào)用者需要確認(rèn)的。這允許調(diào)用者注意到是否被調(diào)用者已經(jīng)崩潰或者發(fā)生了嚴(yán)重的通信故障,并將異常告知用戶。如果這些探測(cè)持續(xù)被確認(rèn)那么調(diào)用者將無(wú)限期等待,因?yàn)樗辣徽{(diào)用者正在(或聲稱)調(diào)用。在我們的實(shí)現(xiàn)中,第一個(gè)探測(cè)是在一個(gè)短暫地延遲之后發(fā)出的,這個(gè)延遲大約相當(dāng)于這兩個(gè)機(jī)器之間的往返時(shí)間。探測(cè)之間的間隔會(huì)逐漸增加,直到大約10分鐘后,探測(cè)會(huì)以每五分鐘一次的頻率發(fā)送。每一個(gè)探測(cè)服從的傳輸策略類似于該調(diào)用中其他包所使用的策略。所以,如果發(fā)生了通信故障,相對(duì)于調(diào)用者等待調(diào)用結(jié)果的總時(shí)間,調(diào)用者將被相當(dāng)迅速地告知。注意這只會(huì)檢測(cè)到通信級(jí)別的故障:如果在調(diào)用過(guò)程中被調(diào)用者發(fā)生死鎖將不會(huì)被檢測(cè)。這符合我們使RPC語(yǔ)義與本地過(guò)程調(diào)用語(yǔ)義類似的原則。我們有可用的語(yǔ)言工具來(lái)檢測(cè)進(jìn)程,并在合適的時(shí)候丟棄它;該工具只適用于等待遠(yuǎn)程調(diào)用的進(jìn)程。
????????重傳和確認(rèn)可能的替代策略是如果它不能夠比預(yù)期的重傳間隔更快地產(chǎn)生下一個(gè)包,那么就讓包的接收者自發(fā)地生成確認(rèn)。這將會(huì)導(dǎo)致在處理持續(xù)時(shí)間較長(zhǎng)的調(diào)用或者調(diào)用間隔時(shí)間過(guò)長(zhǎng)時(shí)保存包的重傳。我們認(rèn)為保存這個(gè)包并不會(huì)帶來(lái)巨大的增益,因?yàn)檫@需要額外的成本去檢測(cè)自發(fā)的確認(rèn)。在我們的實(shí)現(xiàn)中,這種額外的成本體現(xiàn)在維護(hù)一個(gè)額外的數(shù)據(jù)結(jié)構(gòu),以使服務(wù)器上額外的進(jìn)程適時(shí)地產(chǎn)生自發(fā)確認(rèn),加上額外進(jìn)程的成本來(lái)計(jì)算何時(shí)去生成確認(rèn)。事實(shí)上,當(dāng)不需要確認(rèn)時(shí),避免增加額外的成本是很困難的。調(diào)用者則沒(méi)有類似的額外花銷,因?yàn)檎{(diào)用者有一種必要的重傳機(jī)制以應(yīng)對(duì)包的丟失。
????????如果參數(shù)(或結(jié)果)太大以至于無(wú)法以單個(gè)包發(fā)送,它們將以多個(gè)包的形式發(fā)送,但是最后一個(gè)要求顯示確認(rèn)。因此當(dāng)發(fā)送一個(gè)大的調(diào)用參數(shù)時(shí),包將被調(diào)用者和被調(diào)用者交互發(fā)送,發(fā)送者發(fā)送數(shù)據(jù)包而被調(diào)用者回復(fù)確認(rèn)。這允許這種實(shí)現(xiàn)在每一端僅僅使用一個(gè)包緩沖區(qū)來(lái)用于調(diào)用,并避免了在一般的批量數(shù)據(jù)傳輸協(xié)議中發(fā)現(xiàn)的緩沖區(qū)和流控制策略的的必要性。為了能夠消除重復(fù)數(shù)據(jù),該調(diào)用的多個(gè)數(shù)據(jù)包的每一個(gè)都有一個(gè)調(diào)用相關(guān)的序列號(hào)。圖4展示了復(fù)雜調(diào)用的包序列。

????????正如在3.1節(jié)中的描述,這個(gè)協(xié)議旨在處理本地網(wǎng)絡(luò)中的簡(jiǎn)單調(diào)用。如果調(diào)用需要多個(gè)數(shù)據(jù)包來(lái)發(fā)送其參數(shù)和結(jié)果,我們的協(xié)議會(huì)比邏輯上要求更多的數(shù)據(jù)包。我們認(rèn)為這是可以接受的;仍然需要為協(xié)議涉及有效的批量傳輸;我們還沒(méi)有嘗試將RPC和批量數(shù)據(jù)合并到一個(gè)協(xié)議中。為了在一個(gè)方向上傳輸大量數(shù)據(jù),我們的協(xié)議發(fā)送的的數(shù)據(jù)包量達(dá)到了一個(gè)好的批量數(shù)據(jù)協(xié)議可以發(fā)送的兩倍(因?yàn)槲覀兇_認(rèn)每個(gè)包)。這在具有大延遲和高數(shù)據(jù)率的長(zhǎng)途網(wǎng)絡(luò)中尤其不合適。然而,如果通信活動(dòng)可以合理地表示為過(guò)程調(diào)用,那么即使在如此長(zhǎng)的網(wǎng)絡(luò)中,我們的協(xié)議就具有理想的特性。有時(shí)候使用RPC在這些網(wǎng)絡(luò)上進(jìn)行批量數(shù)據(jù)傳輸是可行的,通過(guò)在多個(gè)進(jìn)程中間復(fù)用這些數(shù)據(jù),而每個(gè)進(jìn)程都進(jìn)行單包調(diào)用——那么代價(jià)就只是對(duì)每個(gè)包的額外確認(rèn),在某些情況下這是可以接受的。要求對(duì)每一個(gè)參數(shù)包(除了最后一個(gè))進(jìn)行一個(gè)確認(rèn)的優(yōu)點(diǎn)是這簡(jiǎn)化并優(yōu)化了實(shí)現(xiàn)。用我們的協(xié)議來(lái)進(jìn)行簡(jiǎn)單調(diào)用是可行的,而且能自動(dòng)切換到一個(gè)更常用的協(xié)議來(lái)進(jìn)行復(fù)雜調(diào)用。我們還沒(méi)有探究這種可能性。
3.4 異常捕獲
????????Mesa語(yǔ)言提供了精巧的工具來(lái)通知調(diào)用者調(diào)用過(guò)程的異常。這些被稱為信號(hào)的異??梢员徽J(rèn)為是動(dòng)態(tài)綁定過(guò)程的活動(dòng):當(dāng)引發(fā)異常時(shí),Mesa運(yùn)行時(shí)系統(tǒng)會(huì)動(dòng)態(tài)地掃描調(diào)用堆棧以確定是否有捕獲異常的短語(yǔ)。如果是這樣,catch語(yǔ)句的主體將被執(zhí)行,并在引發(fā)異常時(shí)給出參數(shù)。Catch語(yǔ)句可能會(huì)返回(帶有結(jié)果),并導(dǎo)致執(zhí)行恢復(fù)引發(fā)異常的地方,也可能跳出到一個(gè)閉合的語(yǔ)境上下文中從而終止。在這種終止的情況下,堆棧上的動(dòng)態(tài)更新的過(guò)程活動(dòng)將被釋放(以最近最新的順序)。
????????我們的RPC包忠實(shí)地模仿了這種機(jī)制。協(xié)議中有工具允許服務(wù)器上的進(jìn)程處理一個(gè)傳輸異常包而不是結(jié)果包的調(diào)用。這個(gè)包被調(diào)用者機(jī)器上的RPCRuntime處理仿佛該包是一個(gè)調(diào)用包。但它會(huì)在對(duì)應(yīng)的進(jìn)程中引發(fā)異常而不是發(fā)起一個(gè)新的調(diào)用。如果有適當(dāng)?shù)腸atch語(yǔ)句,則該語(yǔ)句將被執(zhí)行。如果catch語(yǔ)句返回,結(jié)果被返回給被調(diào)用者機(jī)器,事件正常執(zhí)行。如果catch語(yǔ)句因跳轉(zhuǎn)而終止那么被調(diào)用者將被告知,然后釋放相對(duì)應(yīng)的過(guò)程活動(dòng)。由此可看出,我們?cè)俅文7铝吮镜卣{(diào)用的語(yǔ)義。這并不十分準(zhǔn)確:事實(shí)上我們只允許被調(diào)用者機(jī)器傳達(dá)那些調(diào)用者導(dǎo)出的在Mesa接口中定義的異常。這簡(jiǎn)化了我們的實(shí)現(xiàn)(從調(diào)用者機(jī)器的環(huán)境傳輸?shù)奖徽{(diào)用者環(huán)境過(guò)程中傳輸異常的名稱)。在單機(jī)程序中的程序規(guī)范是如果一個(gè)包想傳達(dá)異常給它的調(diào)用者,那么該異常應(yīng)該被定義在該包的接口中;別的異常則應(yīng)該由調(diào)試器處理。我們?yōu)镽PC異常維持并實(shí)施了該規(guī)范。
????????除了被調(diào)用者引發(fā)的異常外,如果有通信問(wèn)題RPCRuntime可能會(huì)引發(fā)呼叫失敗異常。這是我們的客戶注意本地調(diào)用和遠(yuǎn)程調(diào)用間區(qū)別的主要方式。
3.5 使用過(guò)程
????????在Mesa和Cedar中,并發(fā)進(jìn)程可以作為一種內(nèi)置的語(yǔ)言特性使用。在進(jìn)程交換空間創(chuàng)建進(jìn)程和改變處理器狀態(tài)是廉價(jià)的。例如,分叉一個(gè)新的進(jìn)程的花費(fèi)相當(dāng)于十個(gè)本地過(guò)程調(diào)用。一個(gè)進(jìn)程交換包含堆棧評(píng)估和一個(gè)寄存器的交換,以及使一些緩存信息失效。然而,在遠(yuǎn)程調(diào)用的規(guī)模上,進(jìn)程的創(chuàng)建和交換則會(huì)產(chǎn)生很大的成本。這已經(jīng)在Nelson的某些論實(shí)驗(yàn)中展現(xiàn)出來(lái)。因此我們?cè)跇?gòu)建包和設(shè)計(jì)協(xié)議時(shí)有意地保持了低成本。
????????降低成本的第一步是在每個(gè)機(jī)器中維護(hù)一批旨在處理傳入數(shù)據(jù)包的空閑服務(wù)進(jìn)程。這意味著調(diào)用可以在沒(méi)有發(fā)生服務(wù)進(jìn)程創(chuàng)建以及初始化服務(wù)進(jìn)程某些狀態(tài)的情況下就被處理。當(dāng)一個(gè)服務(wù)進(jìn)程完成一個(gè)調(diào)用時(shí),它會(huì)恢復(fù)到空閑狀態(tài)而不是死去。當(dāng)然,如果它們是為了響應(yīng)大量RPC調(diào)用的短暫高峰而被創(chuàng)建,多余的空閑服務(wù)進(jìn)程會(huì)自行終止。
????????每一個(gè)包都包含源和目標(biāo)的進(jìn)程標(biāo)識(shí)符。在那些來(lái)源于調(diào)用者機(jī)器上的包里,源進(jìn)程標(biāo)識(shí)符是調(diào)用的進(jìn)程。在那些源于被調(diào)用者機(jī)器的包里,源進(jìn)程標(biāo)識(shí)符是處理調(diào)用的服務(wù)端進(jìn)程。調(diào)用過(guò)程中,當(dāng)進(jìn)程傳輸包時(shí),它會(huì)根據(jù)該調(diào)用的上一個(gè)包中的源進(jìn)程標(biāo)識(shí)符來(lái)設(shè)置傳輸包中的目的進(jìn)程標(biāo)識(shí)符。如果一個(gè)進(jìn)程正在等待該調(diào)用的下一個(gè)包,該進(jìn)程會(huì)在一個(gè)與我們的以太網(wǎng)終端處理器共享的(簡(jiǎn)單的)數(shù)據(jù)結(jié)構(gòu)中記錄此事實(shí)。當(dāng)終端處理器接收到一個(gè)RPC包,它會(huì)查看該包的目標(biāo)進(jìn)程標(biāo)識(shí)符。如果此時(shí)該機(jī)器上相應(yīng)的進(jìn)程正在等待RPC包,那么該輸入包就直接被分配給該等待進(jìn)程。否則,該包被分配給一個(gè)空閑的服務(wù)進(jìn)程(然后該進(jìn)程去確定這個(gè)包是當(dāng)前請(qǐng)求確認(rèn)調(diào)用的一部分,還是服務(wù)進(jìn)程應(yīng)該處理的一個(gè)新調(diào)用的開(kāi)始,亦或是一個(gè)可以被丟棄的副本)。這意味著大多數(shù)情況下傳入包將會(huì)被分派給一個(gè)需要進(jìn)程交換的進(jìn)程。(當(dāng)然,對(duì)于給定不正確的進(jìn)程標(biāo)識(shí)符的情況,這些進(jìn)程是有彈性的。)當(dāng)調(diào)用活動(dòng)初始化一個(gè)新得調(diào)用時(shí),它會(huì)試圖使用處理該調(diào)用活動(dòng)的上一個(gè)調(diào)用的進(jìn)程標(biāo)識(shí)符作為其目標(biāo)。這是有益的,因?yàn)槟莻€(gè)進(jìn)程很可能正在等待確認(rèn)上一個(gè)調(diào)用的結(jié)果,而且新的調(diào)用包足以確認(rèn)。調(diào)用者使用一個(gè)錯(cuò)誤的目標(biāo)進(jìn)程只會(huì)導(dǎo)致輕微的性能下降,所以調(diào)用者僅僅會(huì)為每個(gè)調(diào)用進(jìn)程維護(hù)一個(gè)簡(jiǎn)單的目標(biāo)進(jìn)程。
????????總之,正常的事件順序如下:一個(gè)希望發(fā)起調(diào)用的進(jìn)程生成該調(diào)用的第一個(gè)包,猜測(cè)一個(gè)可能的合理值作為目標(biāo)進(jìn)程標(biāo)識(shí)符并把源設(shè)為他自己。然后它將該包呈獻(xiàn)給以太網(wǎng)輸出設(shè)備以等待一個(gè)輸入包。在被調(diào)用者機(jī)器上,終端處理器接收到這個(gè)包并記下一個(gè)對(duì)應(yīng)的服務(wù)進(jìn)程。該服務(wù)進(jìn)程處理該包,然后生成響應(yīng)包。在這個(gè)響應(yīng)包中的目標(biāo)進(jìn)程就是調(diào)用者機(jī)器上的那個(gè)正在等待的進(jìn)程。當(dāng)響應(yīng)包到達(dá)調(diào)用者機(jī)器,調(diào)用者機(jī)器上的終端處理器直接把它傳給調(diào)用進(jìn)程。調(diào)用進(jìn)程現(xiàn)在知道了服務(wù)進(jìn)程的進(jìn)程標(biāo)識(shí)符,并將之用于該調(diào)用隨后的包,或者在初始化下一個(gè)調(diào)用時(shí)使用。
????????這種方案的效果是在簡(jiǎn)單調(diào)用中不會(huì)創(chuàng)建任何進(jìn)程,而且在每個(gè)調(diào)用中通常只有四個(gè)進(jìn)程交換。本質(zhì)上,進(jìn)程交換最小可能的數(shù)量是2(除非我們忙碌等待)——我們引入額外的兩個(gè)是因?yàn)閭魅氚潜灰粋€(gè)終端處理器處理而不是由設(shè)備的微代碼直接分配給正確的進(jìn)程(因?yàn)槲覀儧Q定不寫專門的微代碼)。
3.6 其他優(yōu)化
????????上面的討論展示了我們已經(jīng)采用的一些優(yōu)化:我們使用隨后的包來(lái)隱式確認(rèn)先前的包,我們?cè)噲D最小化維護(hù)我們連接的成本,我們避免建立和終止鏈接的花銷,我們減少調(diào)用中需要交換的進(jìn)程數(shù)量。一些別的細(xì)節(jié)的優(yōu)化也有顯著的回報(bào)。
????????我們通過(guò)繞過(guò)對(duì)應(yīng)于正常協(xié)議層級(jí)的軟件層來(lái)傳輸和接收RPC包。(事實(shí)上,我們僅僅在調(diào)用者和被調(diào)用者處于同一網(wǎng)絡(luò)時(shí)這樣做——我們?nèi)匀皇褂没ヂ?lián)網(wǎng)層級(jí)來(lái)路由網(wǎng)絡(luò)。)這獲得了顯著地性能增益,但是某種意義上來(lái)說(shuō)是作弊:這是個(gè)成功的優(yōu)化因?yàn)橹挥蠷PC包能夠使用它。也就是說(shuō),修改了網(wǎng)絡(luò)驅(qū)動(dòng)軟件以讓他將RPC包視作一種特例:如果有10種特例,這將無(wú)利可圖。然而,我們的目標(biāo)希望RPC是一種特例:我們有意于讓它成為一種主要的通信協(xié)議。我們相信這種優(yōu)化的效用不僅僅是我們對(duì)于分層協(xié)議層級(jí)結(jié)構(gòu)的特殊實(shí)現(xiàn)工藝,而是對(duì)于一個(gè)特定的傳輸層協(xié)議而言,通過(guò)繞過(guò)完整通用的低層級(jí)來(lái)顯著提升其性能是可行的。
????????仍然有我們沒(méi)有使用的合理的優(yōu)化:我們?cè)诒镜鼐W(wǎng)絡(luò)通信中避免使用網(wǎng)絡(luò)包的格式,我們可以讓簡(jiǎn)單調(diào)用使用特定的包格式,我們可以實(shí)現(xiàn)目的的網(wǎng)絡(luò)微代碼,我們可以禁止非RPC通信,甚至我們可以通過(guò)忙碌等待保存更多的交換進(jìn)程。我們避免了這些優(yōu)化因?yàn)槟撤N程度的它們中的每一個(gè)都不夠方便,而且我們相信我們已經(jīng)足夠有效地實(shí)現(xiàn)了我們的目標(biāo)。使用它們可能會(huì)在性能中引入額外的兩個(gè)因素。
3.7 安全
????????我們的RPC包和協(xié)議為調(diào)用提供了基本的加密安全工具。這些工具使用Grapevine作為驗(yàn)證服務(wù)(密匙分發(fā)中心)并使用了聯(lián)邦數(shù)據(jù)加密標(biāo)準(zhǔn)。為調(diào)用者提供了識(shí)別被調(diào)用者的保證,反之亦然。我們?yōu)檎{(diào)用和結(jié)果提供了完整的端到端的加密。加密技術(shù)可以避免竊聽(tīng)(隱藏?cái)?shù)據(jù)模式),檢測(cè)修改,重播或者對(duì)調(diào)用進(jìn)行創(chuàng)建。遺憾的是,這里沒(méi)有足夠的空間來(lái)的描述我們?yōu)橹С诌@種機(jī)制而做出的補(bǔ)充和修改。它們將在下一篇論文中報(bào)道。
4 性能
????????正如我們已經(jīng)提到的,Nelson的論文包含了對(duì)幾個(gè)RPC協(xié)議和實(shí)現(xiàn)的廣泛分析,還包括了對(duì)不同性能特征影響因素的測(cè)試。在此我們就不再贅述。
????????我們已經(jīng)對(duì)我們RPC包的使用做了如下測(cè)量。測(cè)量的遠(yuǎn)程調(diào)用發(fā)生在兩臺(tái)連接于以太網(wǎng)中的Dorados之間。該以太網(wǎng)的原始數(shù)據(jù)速率是2.94兆每秒。Dorados運(yùn)行著Cedar。測(cè)量是在與別的用戶共享的以太網(wǎng)上進(jìn)行的,但是該網(wǎng)絡(luò)(除了我們的測(cè)試)負(fù)載很輕,大概在總?cè)萘康?%到10%。表1中的時(shí)間單位都是微秒,通過(guò)對(duì)Daroda的微處理器循環(huán)除以已知的晶體頻率以測(cè)量。它們精確到10%?!????精確到10%???怎么表述】時(shí)間是經(jīng)過(guò)的時(shí)間:包括在等待網(wǎng)絡(luò)所花費(fèi)的時(shí)間以及來(lái)自別的設(shè)備干擾所花的時(shí)間。我們的測(cè)量從用戶程序調(diào)用由server-stub導(dǎo)出到本地的過(guò)程開(kāi)始,直到收到該過(guò)程調(diào)用的響應(yīng)為止。這個(gè)間隔包括花費(fèi)在user-stub中的時(shí)間,每個(gè)機(jī)器上RPCRuntime中的時(shí)間,和花費(fèi)在server-stub,以及服務(wù)器端過(guò)程實(shí)現(xiàn)的時(shí)間(以及在每個(gè)方向上的傳輸時(shí)間)。測(cè)試過(guò)程全部被導(dǎo)出到單個(gè)界面。我們沒(méi)有使用任何加密設(shè)施。
????????我們針對(duì)每個(gè)程序分別測(cè)量了12000個(gè)調(diào)用經(jīng)過(guò)的時(shí)間。表1展示了我們觀察得到的最小的經(jīng)過(guò)時(shí)間,以及平均時(shí)間。我們也呈現(xiàn)了每個(gè)調(diào)用所有包傳輸?shù)目倳r(shí)間(根據(jù)我們協(xié)議中使用的已知包的大小計(jì)算得出,而不是直接測(cè)量)。最后我們展示的是如果用戶程序直接綁定了服務(wù)程序的情況下做出響應(yīng)調(diào)用經(jīng)過(guò)的時(shí)間(例如,發(fā)起一個(gè)純粹的本地調(diào)用,沒(méi)有任何RPC包的參與)。純粹本地調(diào)用的時(shí)間應(yīng)該給讀者提供Dorado處理器速度和Mesa語(yǔ)言的校準(zhǔn)。本地調(diào)用的時(shí)間也指示了總時(shí)間中哪一部分是因?yàn)槭褂肦PC而花費(fèi)的。
????????前五個(gè)過(guò)程分別有0,1,2,4和10個(gè)參數(shù),以及0,1,2,4和10個(gè)結(jié)果,【這兒也覺(jué)得翻譯的優(yōu)點(diǎn)不得勁兒】每一個(gè)參數(shù)或結(jié)果的長(zhǎng)度都是16位。接下來(lái)的五個(gè)過(guò)程調(diào)用都是有一個(gè)參數(shù)和一個(gè)結(jié)果,每個(gè)參數(shù)和結(jié)果分別是大小為1,4,10,40,和100個(gè)詞的數(shù)組。底部的第二行顯示了一個(gè)由引發(fā)了異常但是由調(diào)用者恢復(fù)的過(guò)程調(diào)用。最后一行是同樣由調(diào)用者造成異常但是被釋放的過(guò)程。
????????為了在某一個(gè)方向上傳送數(shù)據(jù),除RPC外的其他協(xié)議具有優(yōu)勢(shì),因?yàn)樗鼈兛梢栽诹硪环较騻魉秃苌俚臄?shù)據(jù)。盡管如此,通過(guò)使用多個(gè)進(jìn)程進(jìn)行交叉并行地遠(yuǎn)程調(diào)用,我們?cè)?兆以太網(wǎng)上的Dorado主內(nèi)存中的數(shù)據(jù)傳輸速率達(dá)到了2兆每秒。
????????我們沒(méi)有測(cè)量導(dǎo)出和導(dǎo)入一個(gè)接口的成本。這兩項(xiàng)操作的時(shí)間主要花在與Grapevine的請(qǐng)求應(yīng)答上。在定位導(dǎo)出器機(jī)器后,調(diào)用導(dǎo)出器以確定調(diào)度器標(biāo)識(shí)符使用了一個(gè)帶有一些數(shù)據(jù)的RPC調(diào)用。

5 現(xiàn)狀和討論
????????我們所描述的包已經(jīng)完全實(shí)現(xiàn)而且在被Cedar的程序員使用。整個(gè)RPCRuntime包有四個(gè)模塊(包交換,包序列化,綁定和安全),源碼總共有大約2200行。其實(shí)Lupine(stub生成器)更大??蛻舳丝梢詫PC用于多個(gè)項(xiàng)目,包括用于Alpine(支持多機(jī)器事物的文件服務(wù)器)的完整通信協(xié)議,以及用于給予以太網(wǎng)的電話和聲音項(xiàng)目的通信控制。(它也已經(jīng)用于兩款網(wǎng)絡(luò)游戲,以為在多臺(tái)機(jī)器上的玩家提供實(shí)時(shí)的通信。)我們所有的客戶都發(fā)現(xiàn)該包使用方便,盡管這兩個(gè)項(xiàng)目還沒(méi)有全面使用。已為BCPL,InterLisp,SmallTalk和C制定了該協(xié)議的實(shí)現(xiàn)。
????????我們?nèi)匀惶幱讷@取使用RPC經(jīng)驗(yàn)的早期階段,確實(shí)有更多的工作需要處理。當(dāng)它被那些正在提交的項(xiàng)目熱情使用時(shí),我們對(duì)RPC設(shè)計(jì)的強(qiáng)度和適用性有了更多的信心?!具@句有不妥】的確在某些情況下,RPC似乎是錯(cuò)誤的通信范式。在這些情況下,基于多波或廣播的解決方案似乎更合適。似乎在分布式系統(tǒng)中有時(shí)候過(guò)程調(diào)用(以及我們語(yǔ)言的并行處理和協(xié)同設(shè)施)不是一個(gè)足夠強(qiáng)大的工具,雖然在單機(jī)中似乎從沒(méi)有任何這種情況出現(xiàn)。
????????我們的愿望之一就是提供一個(gè)高性能和低成本的RPC包,它將鼓勵(lì)從前不可行的新的分布式系統(tǒng)的開(kāi)發(fā)。目前很難去證明我們關(guān)于高性能的主張是正確的,因?yàn)槲覀內(nèi)鄙倌軌蜃C明這種高性能的重要性的演示案例。但是我堅(jiān)信這種例子將會(huì)到來(lái):目前的缺乏是基于這樣一種事實(shí),歷史上分布式通信一直是不方便且緩慢的。我們已經(jīng)看到正在被開(kāi)發(fā)的分布式算法并沒(méi)有被看作一種主要的工程,如果這種趨勢(shì)繼續(xù)我們將取得成功。
????????我們認(rèn)為確定的一個(gè)問(wèn)題是,我們RPC目標(biāo)是否能夠通過(guò)使用那些實(shí)現(xiàn)了適用于RPC策略以及大數(shù)據(jù)量傳輸?shù)耐ㄓ脜f(xié)議實(shí)現(xiàn)足夠的性能水平。當(dāng)然,沒(méi)有完全令人信服的論據(jù)認(rèn)為這是不可能的。但另一方面,我們至今沒(méi)有看到它實(shí)現(xiàn)。
????????我們相信這里討論的RPC包的各部分在幾個(gè)方面都非常有趣。它們代表了RPC設(shè)計(jì)范圍中一些特定的點(diǎn)。我們相信在沒(méi)有采取極端措施,也沒(méi)有犧牲有用的調(diào)用和參數(shù)語(yǔ)義的情況下,我們已經(jīng)實(shí)現(xiàn)了非常好的性能。管理傳輸層連接的技術(shù)能夠最小化通信成本和服務(wù)端必須維護(hù)的狀態(tài),它對(duì)我們服務(wù)端處理大量用戶的實(shí)驗(yàn)非常重要。我們的綁定語(yǔ)義十分強(qiáng)大,但是這一概念對(duì)一個(gè)熟悉單機(jī)綁定的程序員而言十分簡(jiǎn)單。實(shí)現(xiàn)它們非常簡(jiǎn)單且有效。