1974年冬,互聯(lián)網(wǎng)大師 Jon Postel發(fā)表了RFC674:“Procedure Call Protocol Documents,Version 2”,嘗試定義一種在包含70個(gè)節(jié)點(diǎn)的網(wǎng)絡(luò)中共享資源的通用方法。在大師一生中編輯過的無數(shù)個(gè)RFC文檔中,674屬于并不突出的一個(gè),但卻拉開了RPC的序幕。也正是接下來我們故事的開始。
1. 從IPC到RPC
IPC(Inter-Process Communication)即進(jìn)程間通信。指在不同進(jìn)程之間的通信過程。Unix家族中IPC種類繁多,其中有一個(gè)需要特別關(guān)注——Socket(套接字)。與其他IPC類型只支持同機(jī)上進(jìn)程間通信所不同,Socket 廣泛應(yīng)用于不同機(jī)器之間的遠(yuǎn)程通信。
把鏡頭拉到八零年代,自從大神Bill Joy漫不經(jīng)心地對著DARPA官員回答:“我就是邊閱讀協(xié)議文檔,邊敲代碼,就寫出來了”這一刻開始,就注定了Berkeley Socket(伯克利套接字)與眾不同的命運(yùn)。作為TCP協(xié)議的實(shí)現(xiàn),在BSD 4.2中Socket正式面世,彼時(shí)Bill Joy已作為聯(lián)合創(chuàng)始人創(chuàng)辦了SUN公司。Berkeley Socket不僅僅是Unix操作系統(tǒng)進(jìn)行 TCP/IP 通信的實(shí)現(xiàn)基礎(chǔ),更是如今整個(gè)網(wǎng)絡(luò)世界通信的基石,甚至Windows其套接字也脫胎于此。
RPC(Remote Procedure Call)即遠(yuǎn)程過程調(diào)用。RPC是一種技術(shù)思想而非一種規(guī)范。其實(shí)到底什么是RPC,隨著時(shí)間的推移與技術(shù)的演化,已經(jīng)越來越難以定義。但站在八九十年代的當(dāng)口,簡單來說,就是我在本地調(diào)用了一個(gè)函數(shù),或者對象的方法,實(shí)際上是調(diào)用了遠(yuǎn)程機(jī)器上的函數(shù),或者遠(yuǎn)程對象的方法,但是這個(gè)通信過程對于程序員來說是透明的,即達(dá)到了一種位置上的透明性。聽起來真的是我等業(yè)務(wù)邏輯程序員的好幫手,但同樣有持反對意見的人士認(rèn)為:通信的透明,會(huì)對程序員造成通信是無成本的假象,從而濫用以致于增加了通信成本。
當(dāng)然RPC概念本身也適用于除TCP以外的其他傳輸層協(xié)議,但我們用的最多的只有TCP/IP啦。
只需要一個(gè)Wire Protocol,再搭配一個(gè)Name Service(名字服務(wù))就能自定義一個(gè)最簡單的RPC庫了。socket通信,以及序列化反序列化的工作被封裝了RPC框架內(nèi)部,無需程序員手工處理。當(dāng)然一個(gè)成熟的RPC庫,并非如此簡單,它所包含的功能要負(fù)責(zé)的多,亟待解決的問題也棘手的多。
注:所謂Wire Protocol并不是一種網(wǎng)絡(luò)協(xié)議,而是一種數(shù)據(jù)序列化與反序列化的規(guī)則。
從七十年代中到八十年代末,關(guān)于RPC的論文層出不窮。有支持,也有質(zhì)疑,有狂熱,更有批判。就這樣時(shí)間進(jìn)入了下一個(gè)十年。
2. RPC中間件的三國時(shí)代
上個(gè)世紀(jì)最后十年的伊始,面向?qū)ο蟮睦砟钜呀?jīng)走入人們視野,互聯(lián)網(wǎng)還未爆發(fā),但這并不會(huì)阻擋企業(yè)級網(wǎng)絡(luò)規(guī)模的發(fā)展。分布式系統(tǒng)已現(xiàn)端倪,通信是永恒不變的話題。
那些年,不同硬件、不同OS、不同編程語言之間通信與協(xié)作簡直是一場噩夢。1991年,CORBA橫空出世。CORBA全稱Common Object Request Broker Architecture,是OMG(Open Manage Group)組織頒布的標(biāo)準(zhǔn),劃時(shí)代地提出了分布式對象(Distributed object)的技術(shù),自此RPC由原先的面向過程語義進(jìn)化出了面向?qū)ο蟮恼Z義。盡管1.0版本的CORBA只支持C語言的映射,但也著實(shí)讓人們看到了異構(gòu)環(huán)境之間互操作的新希望。
1991年發(fā)生了很多事。
這一年第一個(gè)python編譯器誕生。
而彼時(shí),SUN公司的一個(gè)小組正在攻堅(jiān)O(shè)ak編程語言。
五月,Tim Berners-Lee對外公布了第一個(gè)HTTP版本HTTP/0.9,World Wide Web 首次露面。
八月,在大洋的另一端一個(gè)芬蘭小伙在BBS上發(fā)了一個(gè)交友貼:
“Hello everybody out there using minix——I'm doing a (free) operating system”。
言歸正傳,CORBA使用ORB組件來處理通信過程,ORB(Object Request Broker,
對象請求代理)即CORBA的中間3個(gè)字母。該組件是一個(gè)請求代理,客戶端的代碼只需要向客戶端ORB發(fā)送請求,ORB去定位到服務(wù)端ORB,并且自動(dòng)處理連接與傳送數(shù)據(jù)。那么在兩個(gè)ORB之間如何傳送“對象”呢?答案是GIOP(General Inter ORB Protocol),該協(xié)議規(guī)定了對象的序列化規(guī)則與消息傳遞的規(guī)則。GIOP以短小靈活著稱,但其本身是一個(gè)抽象協(xié)議。IIOP(Internet Inter-ORB Protocol )是GIOP在IP協(xié)議上的具體實(shí)現(xiàn), IIOP就是一種Wire Protocol。
CORBA的一大特點(diǎn)是屏蔽采用了不同技術(shù)棧的服務(wù)端與客戶端之間的差異。為此,它利用IDL(接口描述語言)作為中間語言來共享接口定義。使用編譯工具可以將IDL文件編譯成多種語言的客戶端stub代碼 和
服務(wù)端skeleton代碼,且stub和skeleton可以是不同的編程語言。調(diào)用遠(yuǎn)程方法時(shí),stub代碼會(huì)向ORB發(fā)送請求。
除基本的RPC功能外,還有事務(wù)管理,并發(fā)控制等等功能,由于進(jìn)一步解放了程序員的雙手,使其專注于業(yè)務(wù)邏輯上,因此以CORBA為代表的技術(shù)架構(gòu)也被稱之為——RPC中間件(Middleware)。
1993年,世界上第一款現(xiàn)代意義上的瀏覽器Mosaic發(fā)布,新時(shí)代的大門終于打開。
1995年Oak升級并更名為Java,如今看來昨日黃花的Applet也曾讓人眼前一亮,但Java的未來并不始于此。此后Java推出了RMI,一種基于Java平臺的RPC技術(shù)(此后推出了RMI-IIOP,使得RMI得以和CORBA系統(tǒng)間進(jìn)行通信),后來又推出JavaBean。至此其表現(xiàn)仍算中規(guī)中矩,直到1998年,SUN公司發(fā)布JDK1.2,EJB從此誕生,世人不禁驚呼一聲:“成了”。Java有了自己的分布式對象解決方案。自此Java得以與COBRA和DCOM鼎足而立,三分天下。
同年,CORBA增加了對于Java語言的映射,第二年CORBA3.0標(biāo)準(zhǔn)面世,提出了不用于DCOM、EJB的第三個(gè)組件模型CCM(CORBA Component Model),另外支持映射的語言更多,不僅支持C/C++、Java,還支持骨灰級語言Smalltalk、Ada、COBOL。但最終還是大勢已去,氣數(shù)已盡。給CORBA制定規(guī)范的專家們大部分脫離實(shí)際,且CORBA規(guī)范艱深晦澀。理論脫離實(shí)際,不禁聯(lián)想起OSI/ISO與TCP/IP的故事,讓人唏噓不已。另外廠商們在實(shí)現(xiàn)過程中無法完全理解并遵守該規(guī)范,各有各的解讀,最后導(dǎo)致各家并不兼容。還有一些其他問題,比如由于不同的語言類型系統(tǒng),編程范式千差萬別。因此要想抽象出適合編譯成各種語言接口的IDL語法作為中間語言是十分困難的,但歷史也從來不乏后來者一次又一次的嘗試這么做,不過這是后話了。
Java語言本身跨平臺,Java RMI只專注于一種語言的解決方案,編寫簡單。無需CORBA那樣為了適配各種語言而引入IDL。歷史便是如此有趣,為了適應(yīng)異構(gòu)的網(wǎng)絡(luò)環(huán)境和不同的編程語言,而提出的CORBA技術(shù),因?yàn)槠鋸?fù)雜度無法推行。而只支持一種語言的JavaEE解決方案,因?yàn)楹唵味玫饺藗兊闹С郑M(jìn)而反向助推了Java語言的流行。孰因孰果,難以預(yù)料。只能說不同的時(shí)代,人們的選擇不同。
3. RPC的寓言:十年輪回
RPC的思想自1974年的那篇論文發(fā)表至今已經(jīng)四十余年了。這期間RPC并非一帆風(fēng)順,批判之聲也不絕于耳。
1987年,Tanenbaum教授(就是發(fā)明Minix的譚教授)發(fā)表了論文“A Critique of the Remote Procedure Call Paradigm”,認(rèn)為將本地調(diào)用與遠(yuǎn)程調(diào)用當(dāng)做一樣處理是犯了本質(zhì)錯(cuò)誤,并且達(dá)到通信的完全透明是不可能的,而一旦一個(gè)系統(tǒng)的通信是部分透明,反而會(huì)增加程序員工作的復(fù)雜度。
1994年,時(shí)任SUN公司高級研究員的
(等4人)發(fā)表了著名論文“A Note on Distributed Computing”,痛陳RPC四大罪狀:
- 通信時(shí)延
- 地址空間隔離
- 局部故障
- 并發(fā)問題
當(dāng)然多數(shù)罪狀是分布式系統(tǒng)本身的固有問題。有趣的是Waldo曾提出過一個(gè)十年理論:
每隔十年人們便試圖將本地計(jì)算與遠(yuǎn)程計(jì)算統(tǒng)一,一次又一次。然而本地計(jì)算與遠(yuǎn)程計(jì)算是完全不同的。
十年必是虛數(shù),但這句話倒也值得玩味,在某種程度上暗示了RPC的周期性。Jim Waldo看似是RPC的批判者,但卻對RPC技術(shù)的發(fā)展功不可沒。在任職Sun公司前,Waldo在惠普主導(dǎo)了第一個(gè)ORB的設(shè)計(jì)與開發(fā),從而促進(jìn)了ORB被納入第一版的OMG CORBA規(guī)范之中。后來在SUN公司工作期間,也主導(dǎo)并參與了多項(xiàng)RPC相關(guān)技術(shù)的設(shè)計(jì)研發(fā)工作。
回到之前的時(shí)間線。
1998年,XML 1.0發(fā)布,并成為W3C的推薦標(biāo)準(zhǔn)。此后XML迅速崛起,成為工業(yè)界的新寵。“凡是用XML描述的都是好的,凡是不使用XML的都是垃圾”,在兩個(gè)凡是的方針指導(dǎo)下,XML-RPC應(yīng)運(yùn)而生,但是很快繼任者SOAP就已出現(xiàn)。不要叫他肥皂協(xié)議哦。
Web Service(簡稱WS)使用SOAP協(xié)議作為RPC的序列化標(biāo)準(zhǔn)。SOAP是XML描述的,或者說其本身就是XML的子集,SOAP是一種Wire Protocol,其傳送仍然依賴“介質(zhì)”,這個(gè)介質(zhì)可以 HTTP、TCP 甚至 JMS。另外WS中也存在類似CORBA中IDL的WSDL,用于描述WS接口,并且通過工具可以將其編譯成stub代碼。而WSDL同樣也是XML語言描述的。通過使用WS,可以方便地完成基于SOA架構(gòu)思想的工程實(shí)踐。
世紀(jì)之初,微軟看到了DCOM的暗淡前途,轉(zhuǎn)而強(qiáng)推WS,彼時(shí),微軟與IBM是WS的強(qiáng)力站臺者。好景不長,WS雖然也可以適用于企業(yè)內(nèi)部系統(tǒng)間通信與服務(wù)化的解決方案,但是更多的被人們應(yīng)用在接入層(HTTP),后來隨著以REST風(fēng)格為代表的API技術(shù)的崛起,WS逐漸偃旗息鼓,這也標(biāo)志著RPC技術(shù)在接入層的完敗。
4. 廟堂與江湖:現(xiàn)代RPC
兩千年以后,在互聯(lián)網(wǎng)的泡沫之下,許多中小企業(yè)使用單一的MVC架構(gòu)風(fēng)格即足以滿足要求。許多人都已淡忘了RPC的存在,是否真應(yīng)了十年輪回之說?答案是否定的。其實(shí)RPC從來都未消失,是在大企業(yè)內(nèi)部,RPC技術(shù)一直飛速發(fā)展,尤其是在移動(dòng)互聯(lián)網(wǎng)爆發(fā)之后,后臺瓶頸日益凸顯,RPC再度從幕后走到臺前。RPC中間件成井噴之勢,彼時(shí)現(xiàn)代的RPC框架已經(jīng)吸收了SOA的架構(gòu)思想,以及其他技術(shù)。雖然RPC仍然是中間件的基礎(chǔ),但是后來的附加技術(shù)更加喧賓奪主,且更能代表一個(gè)中間件的特色。相形執(zhí)行,RPC則顯得不那么突出了(不過依然重要)。
2008年,Google開源了Protocol Buffer(簡稱PB),PB不僅兼容大大小小各類編程語言,而且由于是二進(jìn)制協(xié)議,其效率之高,遠(yuǎn)超XML、JSON。開源之后,迅速風(fēng)靡全球。同年,F(xiàn)acebook向Apache貢獻(xiàn)的Thrift正式開源,Thrift提供了多種序列化的方案可供選擇,當(dāng)然也包含二進(jìn)制的。另外PB雖然優(yōu)秀,但終歸只是一個(gè)序列化庫,只是一種高效的Wire Protocol,而Thirft則是一套相對完整解決方案,除RPC的基本功能外,還提供了幾種現(xiàn)成的Server。同樣Thrift包含一個(gè)IDL,兼容常見的編程語言。
2015年,Google將gRPC框架開源,一經(jīng)發(fā)布,迅速獲得廣泛關(guān)注,毫無疑問,gRPC使用PB作為序列化的解決方案,而在傳輸?shù)慕橘|(zhì)上富有創(chuàng)見性的使用了HTTP/2。另外gRPC支持雙向流式通信(bidrectional streaming communication),RPC框架終于不再拘泥于萬年不變的C/S模型,因此gRPC得以更為方便快速地構(gòu)建服務(wù)(SOA或Microservice)。而這正是Thrift的短板。
當(dāng)然企業(yè)的開源項(xiàng)目是需要經(jīng)過修改調(diào)整才釋出的,并非直接拿企業(yè)內(nèi)部的代碼就開源了。因此盡管gRPC在谷歌內(nèi)部運(yùn)行多年,但開源版本的gRPC目前還相對不夠成熟,而Thrift自2007開源以來已經(jīng)歷經(jīng)10年錘煉。但在可以預(yù)見的未來,我相信gRPC與Thrift必將是開源RPC框架中最矚目的兩極。
今天我們可以發(fā)現(xiàn),現(xiàn)在越來越多的前沿技術(shù)由工業(yè)界巨頭和開源社區(qū)所把持。廟堂之高與江湖之遠(yuǎn),在IT領(lǐng)域其實(shí)并不是零和博弈。
我們常說“經(jīng)濟(jì)基礎(chǔ)決定上層建筑”,在后臺技術(shù)領(lǐng)域,決定我們上層建筑的不是經(jīng)濟(jì),正是這些RPC框架。通過使用這些成熟的RPC框架,我們得以站在一個(gè)更高的維度去思考問題。感謝這些企業(yè)以及所有開源社區(qū)的貢獻(xiàn)者。
你以為故事到這里就結(jié)束了嗎?
CORBA沒落之后,一批OMG的實(shí)干派出走,于2002年成立了ZeroC公司,致力于研發(fā)ICE框架,并非為CORBA續(xù)命,ICE被稱之為反叛之冰。Hadoop之父Doug Cutting由于不滿于Thrift設(shè)計(jì)哲學(xué)中的中庸之道,開始了繼續(xù)造輪子之路,因此誕生了Avro。放眼國內(nèi),2011年,開源大戶阿里也曾開源自研RPC框架——Dubbo。但近兩年又風(fēng)聞其已轉(zhuǎn)向新一代框架——HSF(High Speed Framework)。2014年,F(xiàn)acebook再度開源輕量級Thrift框架——fbthrift……
RPC、中間件、服務(wù),這個(gè)江湖很多故事沒有提及,并且新的故事還在繼續(xù)。唱衰RPC也好,唱紅RPC也罷。說“炒冷飯”也好,說“取其精華,去其糟粕”也罷。我們所處的環(huán)境在不停變化,所面臨的問題也一變再變。RPC當(dāng)然不是銀彈,也或許真的深陷十年輪回,但我們必然不是西西弗斯。
技術(shù)終將過時(shí),后浪終將拍打前浪。前人在技術(shù)道路上的探索,或許我們早已遺忘。但我相信那些熠熠生輝的名字都化作了光。而今日技術(shù)上所有的輝煌,都是站在巨人的肩膀上。
參考資料&推薦閱讀
- RPC
- RPC is Not Dead: Rise, Fall and the Rise of Remote Procedure Calls
- CORBA的興衰
- CORBA簡介
- CORBA與RPC的比較(轉(zhuǎn))
- CORBA GIOP消息格式學(xué)習(xí)
- gRPC官網(wǎng)
- Apache Thrift官網(wǎng)
- fbthrift github
- finagle官網(wǎng)
- Dubbo官網(wǎng)
- A Critique of the Remote Procedure Call Paradigm
- A Note on Distributed Computing