<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          詳解微服務技術中進程間通信

          共 7805字,需瀏覽 16分鐘

           ·

          2021-06-07 01:33

          在單體應用中,一個組件調用其它組組件時,是通過語言級的方法或者函數(shù)調用,而一個基于微服務的應用是運行于多個服務器上的分布式系統(tǒng),每個服務實例是一個典型的進程。所以,如下圖顯示的,服務必須通過內部進程交互機制(IPC)進行交互。



          推薦閱讀:

          世界的真實格局分析,地球人類社會底層運行原理

          企業(yè)IT技術架構規(guī)劃方案

          論數(shù)字化轉型——轉什么,如何轉?

          企業(yè)10大管理流程圖,數(shù)字化轉型從業(yè)者必備!

          【中臺實踐】華為大數(shù)據(jù)中臺架構分享.pdf

          華為的數(shù)字化轉型方法論

          華為如何實施數(shù)字化轉型(附PPT)

          超詳細280頁Docker實戰(zhàn)文檔!開放下載

          華為大數(shù)據(jù)解決方案(PPT)

          交互風格


          在為一個服務選擇IPC的時候,首先考慮一下這些服務是如何交互的是很有用處的。有多種client/server的交互風格,它們可以通過兩個維度分類,第一種維度是交互是一對一,還是一對多的:


          • 一對一:每個客戶端的請求只被一個服務實例處理

          • 一對多:每個客戶端請求被多個服務實例處理

          • 第二種維度是交互是同步的還是異步的:

          • 同步:客戶端期望從服務得到及時的返回,并且甚至可以因此阻塞片刻

          • 異步:客戶端不會在等待返回結果的時候阻塞,返回結果也沒必要立刻被發(fā)送出來


          下表顯示出各種交互風格:

           

          一對一

          一對多

          同步

          請求/響應

           

          異步

          通知

          發(fā)布/訂閱

          請求/異步響應

          發(fā)布/異步響應


          有如下幾種一對一的交互形式:


          請求/響應:客戶端發(fā)送一個請求給一個服務,并且等待響應結果,客戶端期望結果能快速的返回,在一個基于線程的應用中,發(fā)送請求的線程甚至可能在等待的時候被阻塞。

          • 通知(一種單向請求):客戶端發(fā)送一個請求到服務,但不期望有響應發(fā)送回來。

          • 請求/異步響應:客戶端往服務發(fā)送請求,響應結果異步的返回。客戶端不會在等待的時候阻塞,而且客戶端是基于響應在一段時間之后才返回的假設來設計的。

          有如下幾種一對多的交互形式:

          • 發(fā)布/訂閱:客戶端發(fā)布消息,消息被零或者多個感興趣的服務消費

          • 發(fā)布/異步響應:客戶端發(fā)布一個請求消息,等待固定的一段時間,以獲得從感興趣的服務返回的響應結果


          每個服務一般都使用這幾種交互風格的組合風格。對于一些服務來說,單一的IPC機制就足夠了,而其它的服務可能需要組合使用若干種IPC機制。下面的圖給出當客戶請求行程時,在一個打車應用可能出現(xiàn)的一些交互。

          這些服務使用了通知,請求/響應,發(fā)布/訂閱的交互方式。比如說,一個乘客的智能手機向行程管理服務發(fā)送了一個上車請求,行程管理服務通過請求/響應方式向乘客服務確認乘客的賬戶是否是活躍賬戶,行程管理服務于是創(chuàng)建一個行程訂單,并且用發(fā)布/訂閱方式通知其它的服務,包括一個分發(fā)服務,用以定位空閑的司機。


          定義API


          服務的API是服務與它所有的客戶端之間的一種契約,不管選用何種IPC機制,使用一些接口定義語言(IDL),對于精確定義服務API是很重要的,甚至已經有一些關于使用API-first approach來定義服務的好的討論。


          開發(fā)一個微服務從書寫接口定義以及與客戶端開發(fā)人員一起review這些接口定義開始,在不斷的對這些API定義進行迭代,最終才算是實現(xiàn)了一個微服務。這種基于前端的設計方式,增加了構建出符合客戶端需求的機會。

           

          在文章的后面你會看到,API定義的特性依賴與你使用的IPC機制,如果你使用消息機制,API就會涉及到消息通道和消息類型;如果你選用HTTP方式,那么API就會包含一些URL和請求/響應的格式,之后我們會詳細的介紹IDL。

           

          API的演進


          一個服務的API會隨著時間而經常變化。在單體應用中,通常是很直接的修改API,再更新所有的調用之處,但在基于微服務的應用中,情況要困難得多,甚至你API的所有消費者是同一個應用中的其它服務。你通常不能強迫所有的客戶端步調一致的升級它們的服務。而且你可能會大量的開發(fā)服務的新版本,于是新舊版本的服務會同時運行,制定一個處理這種問題的戰(zhàn)略原則顯得很重要。

           

          如何處理一個API的變化,取決于這種變化的多少。有的變化很少,可以向后兼容之前的版本,比如,你可能只是在請求或者響應格式中增加一些屬性。設計出具有魯棒原則的客戶端和服務是有意義的,那些使用更舊的API的客戶端應該能夠繼續(xù)和新版本的服務工作得很好,服務會給請求中沒有的屬性提供默認值,客戶端會忽略那些響應中額外的屬性。使用IPC機制和消息格式是重要的,讓你能輕易的演進API。

           

          有時候,你不得不對API做一些主要的、不兼容的改動。既然不能強制客戶端立刻升級,那這個服務必須能夠支持舊版本的API一定時期。如果你用的是基于HTTP的機制,如REST,一個好的辦法是在API的URL中嵌入版本號。每個服務實例應該可以同時處理不同版本的API請求,或者是部署不同的服務實例來處理不同的API版本。

           

          處理部分失敗


          在之前關于API網關的文章中曾經提到,在分布式系統(tǒng)中,總會存在部分失敗的風險,既然客戶端和服務是分開的進程,一個服務可能不能對一個客戶端請求及時的返回結果,服務也可能因為錯誤或者是維護停止了,亦或是因為過載而對請求響應緩慢。

           

          比如說,如上篇文章中提到的那個產品詳頁的場景,試想一下如果那個推薦服務失去響應了,客戶端的一個本地實現(xiàn)就可能在無限的等待響應中被阻塞了,這不僅會帶來劣質的用戶體驗,而且在很多應用中,這會消耗寶貴的資源,如一個線程,最終運行時環(huán)境會線程耗盡,變成無法響應,正如下圖所示。



          為了避免這種問題,把你的服務設計成能處理部分失敗是很有必要的。

           

          Netfix給我們提出了一個可以遵循的好辦法,其中處理部分失敗的原則包括:


          • 網絡超時:永遠不要無限的阻塞,總是在等待響應中使用超時,使用超時來確保資源不會被無限綁定。

          • 限制未解決的請求數(shù)量:對一個客戶端持有的對一個服務沒有完成的請求,應該設定上限值,這個上限一旦達到,發(fā)送更多的請求就會是無意義的,而且這些新的請求需要立刻返回為失敗。

          • 回路中斷器模式:跟蹤成功請求和失敗請求的數(shù)量,如果錯誤率超過了一個事先配置的閾值就開啟回路中斷器,讓進一步的嘗試立刻失敗。如果大量的請求正處在失敗中,那就預示服務不可用,而且發(fā)送請求也是無意義的。經過超時周期之后,客戶端應該再進行嘗試發(fā)送請求,如果請求成功,就關閉回路中短器。

          • 提供回滾機制:一個請求失敗時,執(zhí)行回滾邏輯,比如說返回緩存的數(shù)據(jù)或者是默認值,也或者諸如一個關于推薦商品的空集合。


          Netfix Hystrix是這些模式的一種開源實現(xiàn),如果你正在使用JVM,你肯定會考慮使用Hystrix的,如果你運行的是一個非JVM的環(huán)境,同樣需要考慮使用一個類似的庫。


          IPC技術


          有許多IPC技術可供選擇,如同步的請求/響應機制,這里面有基于HTTP方式的REST和Thrift,另外有基于消息的異步通信機制,如AMQP和STOMP。其中消息的格式也是多種多樣的,有一些是人可讀的,比如JSON和XML,有些是二進制格式的(這種更高效),如Avro和緩存協(xié)議。稍后我們介紹同步的IPC機制,但在這之前,先討論異步的IPC機制。


          異步(基于消息的通信)


          當使用消息時,進程間通過異步的交換消息來通信。客戶端通過向服務發(fā)送消息來發(fā)送請求,如果期望服務返回應答,那么它發(fā)送回一個獨立的消息給客戶端。由于通信是異步的,客戶端不會阻塞在等待返回結果上,客戶端應該是基于不會立刻收到返回結果的假設來實現(xiàn)。

           

          消息包含消息頭(如發(fā)送者這樣的元數(shù)據(jù))和消息體,各種消息在通道上交換,任意數(shù)量的生產者都能往通道上發(fā)送消息,同樣,任意數(shù)量的消費者也能從這個通道接收消息。有兩種類型的通道:點對點通道和發(fā)布/訂閱通道。點對點的通道只給連接到這個通道上的眾多消費者中的一個發(fā)送消息,服務使用這種通道往往是采用前面提到的一對一的交互風格。發(fā)布/訂閱這種通道,是給連接到它之上的所有消費者發(fā)送消息,這種通道往往被一對多風格的服務采用。


          下圖描述的是,在打車應用中,發(fā)布/訂閱的通道是如何使用的

           

          行程管理服務向發(fā)布/訂閱通道發(fā)送一個行程創(chuàng)建的消息,以此告訴那些對此感興趣的服務(比如說分發(fā)器服務),一個新行程創(chuàng)建了。分發(fā)器服務找到一個可用的司機,將一個需要提名司機的消息寫入發(fā)布/訂閱通道,這樣其它的服務就能得到這個通知。

           

          有許多消息系統(tǒng)可供選擇,你應該選擇那些能支持多種開發(fā)語言的。一些消息系統(tǒng)支持AMQP和STOMP這些標準協(xié)議,其它的系統(tǒng)是一些專有而且文檔化的協(xié)議。現(xiàn)在有不少開源的消息系統(tǒng),其中包括RabbitMQ,Apache Kafka,Apache ActiveMQ和NSQ。總體上看,他們都支持消息格式和通道,都是可靠的、高性能的和可擴展的,但它們在消息模型細節(jié)方面有著巨大的差異。

           

          使用消息有諸多優(yōu)點:


          • 把客戶端從服務中解耦出來:客戶端只需要簡單的往正確的通道里發(fā)消息,它完全不用感知服務實例,它不需要通過發(fā)現(xiàn)機制來定位服務實例所在的位置。

          • 消息緩沖:在使用HTTP這種同步的請求/響應協(xié)議時,客戶端和服務都必須在交換數(shù)據(jù)的時候保持可用。與此相反,消息代理會將寫到通道里面的消息隊列化,直到消費者能夠處理這些消息。這意味著,比如,對訂單的消息進行簡單的隊列化之后,即使是訂單填寫系統(tǒng)響應緩慢或者不可用,一個在線商店仍然可以接收到來自客戶的訂單。

          • 靈活的客戶——服務交互:消息機制支持之前提到的所有交互風格。

          • 顯式的進程間通信:基于RPC的機制能夠讓調用遠端的服務看起來如同調用本地服務,但由于存在物理規(guī)則和部分失敗的可能,這些機制都有較大不同。消息機制讓這些不同之處變得很顯式,這樣程序員不用陷于安全失誤當中。

           

          當然,消息機制也有缺點:


          • 額外的操作復雜性:消息系統(tǒng)是另外一個系統(tǒng),必須安裝,配置和操作,消息代理必須高可用,要不然整個個系統(tǒng)的可靠性將受到影響。

          • 實現(xiàn)基于請求/響應的交互比較復雜:請求/響應風格的交互要求一些實現(xiàn)上的工作,每個請求消息必須包含一個應答通道ID和關聯(lián)ID,服務將相關ID包含在響應的消息中,并發(fā)送到響應通道,客戶端就通過這個相關ID來將響應和請求匹配起來。使用IPC機制來直接支持請求/響應通常簡單一些。


          現(xiàn)在我們已經討論完了基于消息的IPC,接下來探討一下基于請求/響應的IPC


          同步的請求/響應IPC


          在同步的、基于請求/響應的IPC機制中,客戶端向服務發(fā)送一個請求,服務處理這個請求,并將響應發(fā)回。在許多客戶端的實現(xiàn)中,發(fā)送請求的線程會在等待響應的時候阻塞。


          而另一些客戶端的實現(xiàn),可能使用異步的、事件驅動的方式,請求相關的代碼會被封裝在Futrues或者Rx Observables這樣的庫中。和前面介紹的消息機制不同,在這種IPC里客戶端是假設響應會及時返回。有很多協(xié)議可供選擇,其中有兩種很流行:REST和Thrift。我們先來看看REST


          REST


          目前,使用RESTful風格來開發(fā)API是很流行的做法,REST是使用HTTP的IPC機制,REST的一個關鍵概念是資源,資源代表一個業(yè)務對象,比如說一個客戶,一個產品,或者是一些業(yè)務對象的集合。REST使用HTTP的方法來操作資源,通過URL來引用資源。比如,GET請求會返回一個資源的信息,返回結果用XML文檔或者JSON對象來表示,POST請求創(chuàng)建一個資源,PUT請求是更新一個資源。REST的創(chuàng)建者Roy Fielding的描述如下:

           

          “REST提供一個架構約束的集合,當被整體應用時,強調組件交互的擴展性、接口的普遍性,組件的獨立部署,減少交互延時的中間組件,增強的安全性以及對遺留系統(tǒng)的封裝。”

           

          下圖展示了打車應用中使用REST的一個場景。


          乘客的智能手機向行程管理服務發(fā)送創(chuàng)建行程的請求,這個時候一個POST請求發(fā)送到服務端,請求創(chuàng)建一個/trips資源,行程管理服務隨后發(fā)送一個GET請求到乘客管理服務,來獲取乘客的信息,在確認了這個乘客是一個授權過可以創(chuàng)建行程的用戶之后,行程管理服務正式的創(chuàng)建出行程,并且返回一個201結果給智能手機。

           

          很多開發(fā)者都聲稱他們的HTTP API都是RESTful的,但如Fielding在他的這篇博客里描述的,其實他們不一定都是。Leonard Richardson給出了一個很有用的REST成熟度模型,包含如下一些級別:


          • 級別0:客戶端通過發(fā)送基于HTTP的POST請求到唯一的URL服務端,每個請求指定要執(zhí)行的動作,動作的對象(比如業(yè)務對象),以及其它任何參數(shù)。

          • 級別1:支持資源的概念,為了在一個資源上執(zhí)行動作,客戶端需要在POST請求中指定執(zhí)行的動作和所有的參數(shù)。

          • 級別2:API使用HTTP的動詞來執(zhí)行動作:GET用來獲取,POST用來創(chuàng)建,PUT用來修改。請求要求參數(shù)和請求體,如果有,還需要指定動作的參數(shù),這樣服務就可以利用頁面系統(tǒng)的一些基礎設施,如緩存GET請求。

          • 級別3:這個級別的API是基于HATEOAS(超文本應用狀態(tài)引擎)原則的,基本思想是在GET請求返回的代表資源的響應中,需要包含一些鏈接,這些鏈接對應與可對這個資源執(zhí)行的動作。舉個例子,訂單的GET請求的返回結果中會包含操作的鏈接,其中有取消訂單的操作鏈接,客戶端可以從結果中找到這個鏈接,使用它取消訂單。

          • HATEOAS的優(yōu)勢在于不再需要將URL硬編碼到客戶端的代碼里面去了,另一個好處是由于資源的返回結果中已經包含允許的操作的鏈接,客戶端不用去猜測當前狀態(tài)下能對資源做哪些操作了。

           

          使用基于HTTP的協(xié)議的好處有:


          • HTTP對與大家來說簡單而熟悉。

          • 可以用一些有Postman這種插件的瀏覽器來測試API,也可以用curl這種命令行工具來測試(返回結果是用JSON或者其它類型的文本格式)

          • 直接支持請求/響應風格的通信

          • HTTP是防火墻友好的

          • 不需要有中間代理,這讓系統(tǒng)的架構得到簡化

           

          使用HTTP也有缺點:


          • 只支持請求/響應的交互風格,這使得在使用HTTP來發(fā)送通知的時候,服務端必須總是發(fā)送HTTP響應回來。

          • 因為客戶端和服務端直接通信(中間沒有緩沖消息),他們在交換信息期間必須同時處于運行狀態(tài)。

          • 客戶端必須知道每個服務實例的地址(比如URL),正如在上一篇文章中描述的,在現(xiàn)代應用中,這倒不是個重要的問題,一般客戶端都需要使用服務發(fā)現(xiàn)機制來定位服務實例的位置。

           

          開發(fā)者社區(qū)最近發(fā)現(xiàn)了接口定義語言對RESTful API的新價值,這方面有一些選擇,包括RAML和Swagger。一些諸如Swagger的IDL允許定義出請求和響應消息的格式,其它一些諸如RAML的IDL則要求使用獨立的規(guī)范,如JSON schema。在描述API的同時,IDL一般也有工具來給接口定義生成客戶端樁和服務端骨架。


          Thrift


          Apache Thrift是REST的一種有趣的替代方案,它是開發(fā)跨語言RPC客戶端和服務端的框架,Thrift提供C語言風格的IDL來定義你的API,使用Thrift編譯器生成客戶樁和服務骨架,編譯器能夠生成各種語言的代碼,包括C++,Java,Python,PHP,Ruby,Erlang和Node.js。

           

          一個Thrift接口包含一個或多個服務,定義服務與定義Java接口類似,是一些強輸入方法的集合,Thrift方法可以定義城返回一個值(也可能是void的),或者定義成單向方法。返回一個值的方法都會實現(xiàn)請求/響應的交互風格。客戶端等待請求,并且有可能拋出異常。單向方法其實是符合通知風格的交互,服務端不會發(fā)送響應。

           

          Thrift支持多鐘消息格式:JSON,二進制,緊湊的二進制。二進制格式通常比JSON更高效一些,因為解析它更快。對于緊湊二進制格式,如它的名字一樣,它是節(jié)省空間的消息。而JSON,當然是對人和瀏覽器友好的一種格式。在Thrift中,也可以自己選擇傳輸協(xié)議,其中包括原始TCP和HTTP。TCP一般比HTTP更高效一些,當然,HTTP是對防火墻、瀏覽器和人友好的。


          消息格式


          前面已經討論過HTTP和Thrift,現(xiàn)在介紹消息格式的問題。如果使用消息系統(tǒng)或者REST,需要確定消息格式。其它一些如Thrift這種IPC機制只支持有限的集中消息格式,或許就一種而已。在任何一種情況中,使用跨語言的消息格式是很重要的。甚至你現(xiàn)在只是用一種語言來實現(xiàn)你的微服務,很可能你將來會使用其它的語言。

           

          有兩種主要的消息格式:文本和二進制碼。基于文本的格式有JSON,XML這些。它們的優(yōu)點在于是人可讀的,而且是自描述的。在JSON中,對象的屬性被表示成名稱-值對的集合。類似的,在XML中,屬性被表示成名字元素和值。這可以讓消息消費者能夠找到感興趣的值,同時忽略其它的。而且,對格式的小量改動可以容易的兼顧到后向兼容性。

           

          XML文檔的結構是在XML schema文件中定義的,漸漸的社區(qū)的開發(fā)者意識到JSON也需要類似的機制,其中一個解決辦法是使用JSON schema,以獨立方式存在或者是如Swagger這種IDL的一部分。

           

          基于消息的格式的一個缺點是比較繁瑣,尤其是XML。因為消息是自描述的,除了包含屬性的值之外,消息里還包含屬性的名稱。另外一個劣勢是,解析消息文本需要開銷。基于這些,你可能更想使用二進制碼格式

           

          有幾種二進制格式可供選擇。當用Thrift RPC,你可以選擇二進制的Thrift。如果使用消息格式,比較流行的選擇是Protocol Buffers和Apache Avro。這兩種格式都提供輸入的IDL來定義消息結構。不同之處在于,Protocol Buffers使用標簽域,而Avro,它的消費者在翻譯消息前,需要提前知道消息的schema。這篇博客完美解釋了Thrift, Protocol Buffers和Avro的異同之處。


          總結


          微服務必須使用一種進程間通信機制,當設計你的服務如何通信時,需要考慮各種問題:服務如何交互,如何為每個服務設計API,如何演進API,以及如何處理部分失敗問題。有兩種微服務可用的IPC機制,異步的消息機制和同步的請求/響應機制。在這一系列文章的下一篇文章中,我們會研究在微服務架構中的服務發(fā)現(xiàn)問題。

           

          英文原文:

          https://www.nginx.com/blog/building-microservices-inter-process-communication/


          推薦閱讀:

          世界的真實格局分析,地球人類社會底層運行原理

          企業(yè)IT技術架構規(guī)劃方案

          論數(shù)字化轉型——轉什么,如何轉?

          企業(yè)10大管理流程圖,數(shù)字化轉型從業(yè)者必備!

          【中臺實踐】華為大數(shù)據(jù)中臺架構分享.pdf

          華為的數(shù)字化轉型方法論

          華為如何實施數(shù)字化轉型(附PPT)

          超詳細280頁Docker實戰(zhàn)文檔!開放下載

          華為大數(shù)據(jù)解決方案(PPT)



          瀏覽 79
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  韩国精品三级 | 熟女少妇内射日韩亚洲 | 亚洲A∨剧情中文 | 日韩欧美一级视频 | 黄色视频网站在线观看免费 |