一杯清茶

          導(dǎo)航

          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          隨筆分類

          文章分類

          收藏夾

          隨筆檔案

          文章檔案

          相冊(cè)

          統(tǒng)計(jì)

          留言簿

          Oracle SQL/PLSQL

          PowerDesigner教程系列

          Struts2.0

          web開發(fā)

          三人行

          從事RCP開發(fā)的同行

          工作流和權(quán)限設(shè)置

          閱讀排行榜

          評(píng)論排行榜

          微服務(wù)實(shí)戰(zhàn)(三):深入微服務(wù)架構(gòu)的進(jìn)程間通信

          【編者的話】這是采用微服務(wù)架構(gòu)創(chuàng)建自己應(yīng)用系列第三篇文章。第一篇介紹了微服務(wù)架構(gòu)模式,和單體式模式進(jìn)行了比較,并且討論了使用微服務(wù)架構(gòu)的優(yōu)缺點(diǎn)。第二篇描述了采用微服務(wù)架構(gòu)應(yīng)用客戶端之間如何采用API Gateway方式進(jìn)行通信。在這篇文章中,我們將討論系統(tǒng)服務(wù)之間如何通信。

          簡(jiǎn)介

          在單體式應(yīng)用中,各個(gè)模塊之間的調(diào)用是通過編程語(yǔ)言級(jí)別的方法或者函數(shù)來(lái)實(shí)現(xiàn)的。但是一個(gè)基于微服務(wù)的分布式應(yīng)用是運(yùn)行在多臺(tái)機(jī)器上的。一般來(lái)說(shuō),每個(gè)服務(wù)實(shí)例都是一個(gè)進(jìn)程。因此,如下圖所示,服務(wù)之間的交互必須通過進(jìn)程間通信(IPC)來(lái)實(shí)現(xiàn)。

          Richardson-microservices-part3-monolith-vs-microservices-1024x518.png


          后面我們將會(huì)詳細(xì)介紹IPC技術(shù),現(xiàn)在我們先來(lái)看下設(shè)計(jì)相關(guān)的問題。

          交互模式

          當(dāng)為某一個(gè)服務(wù)選擇IPC時(shí),首先需要考慮服務(wù)之間如何交互。客戶端和服務(wù)器之間有很多的交互模式,我們可以從兩個(gè)維度進(jìn)行歸類。第一個(gè)維度是一對(duì)一還是一對(duì)多:

          • 一對(duì)一:每個(gè)客戶端請(qǐng)求有一個(gè)服務(wù)實(shí)例來(lái)響應(yīng)。
          • 一對(duì)多:每個(gè)客戶端請(qǐng)求有多個(gè)服務(wù)實(shí)例來(lái)響應(yīng)

          第二個(gè)維度是這些交互式同步還是異步:

          • 同步模式:客戶端請(qǐng)求需要服務(wù)端即時(shí)響應(yīng),甚至可能由于等待而阻塞。
          • 異步模式:客戶端請(qǐng)求不會(huì)阻塞進(jìn)程,服務(wù)端的響應(yīng)可以是非即時(shí)的。

          下表顯示了不同交互模式:

          74.pic_.jpg


          一對(duì)一的交互模式有以下幾種方式:

          • 請(qǐng)求/響應(yīng):一個(gè)客戶端向服務(wù)器端發(fā)起請(qǐng)求,等待響應(yīng)。客戶端期望此響應(yīng)即時(shí)到達(dá)。在一個(gè)基于線程的應(yīng)用中,等待過程可能造成線程阻塞。
          • 通知(也就是常說(shuō)的單向請(qǐng)求):一個(gè)客戶端請(qǐng)求發(fā)送到服務(wù)端,但是并不期望服務(wù)端響應(yīng)。
          • 請(qǐng)求/異步響應(yīng):客戶端發(fā)送請(qǐng)求到服務(wù)端,服務(wù)端異步響應(yīng)請(qǐng)求。客戶端不會(huì)阻塞,而且被設(shè)計(jì)成默認(rèn)響應(yīng)不會(huì)立刻到達(dá)。

          一對(duì)多的交互模式有以下幾種方式:

          • 發(fā)布/ 訂閱模式:客戶端發(fā)布通知消息,被零個(gè)或者多個(gè)感興趣的服務(wù)消費(fèi)。

          • 發(fā)布/異步響應(yīng)模式:客戶端發(fā)布請(qǐng)求消息,然后等待從感興趣服務(wù)發(fā)回的響應(yīng)。

          每個(gè)服務(wù)都是以上這些模式的組合,對(duì)某些服務(wù),一個(gè)IPC機(jī)制就足夠了;而對(duì)另外一些服務(wù)則需要多種IPC機(jī)制組合。下圖展示了在一個(gè)打車服務(wù)請(qǐng)求中服務(wù)之間是如何通信的。

          Richardson-microservices-part3-taxi-service-1024x609.png


          上圖中的服務(wù)通信使用了通知、請(qǐng)求/響應(yīng)、發(fā)布/訂閱等方式。例如,乘客通過移動(dòng)端給『行程管理服務(wù)』發(fā)送通知,希望申請(qǐng)一次出租服務(wù)。『行程管理服務(wù)』發(fā)送請(qǐng)求/響應(yīng)消息給『乘客服務(wù)』以確認(rèn)乘客賬號(hào)是有效的。緊接著創(chuàng)建此次行程,并用發(fā)布/訂閱交互模式通知其他服務(wù),包括定位可用司機(jī)的調(diào)度服務(wù)。

          現(xiàn)在我們了解了交互模式,接下來(lái)我們一起來(lái)看看如何定義API。

          定義API

          API是服務(wù)端和客戶端之間的契約。不管選擇了什么樣的IPC機(jī)制,重要的是使用某種交互式定義語(yǔ)言(IDL)來(lái)精確定義一個(gè)服務(wù)的API。甚至有一些關(guān)于使用API first的方法(API-first approach)來(lái)定義服務(wù)的很好的理由。在開發(fā)之前,你需要先定義服務(wù)的接口,并與客戶端開發(fā)者詳細(xì)討論確認(rèn)。這樣的討論和設(shè)計(jì)會(huì)大幅度提到API的可用度以及滿意度。

          在本文后半部分你將會(huì)看到,API定義實(shí)質(zhì)上依賴于選擇哪種IPC。如果使用消息機(jī)制,API則由消息頻道(channel)和消息類型構(gòu)成;如果選擇使用HTTP機(jī)制,API則由URL和請(qǐng)求、響應(yīng)格式構(gòu)成。后面將會(huì)詳細(xì)描述IDL。

          API的演化

          服務(wù)端API會(huì)不斷變化。在一個(gè)單體式應(yīng)用中經(jīng)常會(huì)直接修改API,然后更新給所有的調(diào)用者。而在基于微服務(wù)架構(gòu)應(yīng)用中,這很困難,即使只有一個(gè)服務(wù)使用這個(gè)API,不可能強(qiáng)迫用戶跟服務(wù)端保持同步更新。另外,開發(fā)者可能會(huì)嘗試性的部署新版本的服務(wù),這個(gè)時(shí)候,新舊服務(wù)就會(huì)同事運(yùn)行。你需要知道如何處理這些問題。

          你如何處理API變化,這依賴于這些變化有多大。某些改變是微小的,并且可以和之前版本兼容。比如,你可能只是為某個(gè)請(qǐng)求和響應(yīng)添加了一個(gè)屬性。設(shè)計(jì)客戶端和服務(wù)端時(shí)候應(yīng)該遵循健壯性原理,這很重要。客戶端使用舊版API應(yīng)該也能和新版本一起工作。服務(wù)端仍然提供默認(rèn)響應(yīng)值,客戶端忽略此版本不需要的響應(yīng)。使用IPC機(jī)制和消息格式對(duì)于API演化很有幫助。

          但是有時(shí)候,API需要進(jìn)行大規(guī)模的改動(dòng),并且可能與之前版本不兼容。因?yàn)槟悴豢赡軓?qiáng)制讓所有的客戶端立即升級(jí),所以支持老版本客戶端的服務(wù)還需要再運(yùn)行一段時(shí)間。如果你正在使用基于基于HTTP機(jī)制的IPC,例如REST,一種解決方案是把版本號(hào)嵌入到URL中。每個(gè)服務(wù)都可能同時(shí)處理多個(gè)版本的API。或者,你可以部署多個(gè)實(shí)例,每個(gè)實(shí)例負(fù)責(zé)處理一個(gè)版本的請(qǐng)求。

          處理部分失敗

          在上一篇關(guān)于API gateway的文章中,我們了解到分布式系統(tǒng)中部分失敗是普遍存在的問題。因?yàn)榭蛻舳撕头?wù)端是都是獨(dú)立的進(jìn)程,一個(gè)服務(wù)端有可能因?yàn)楣收匣蛘呔S護(hù)而停止服務(wù),或者此服務(wù)因?yàn)檫^載停止或者反應(yīng)很慢。

          考慮這篇文章中描述的部分失敗的場(chǎng)景。假設(shè)推薦服務(wù)無(wú)法響應(yīng)請(qǐng)求,那客戶端就會(huì)由于等待響應(yīng)而阻塞,這不僅會(huì)給客戶帶來(lái)很差的體驗(yàn),而且在很多應(yīng)用中還會(huì)占用很多資源,比如線程,以至于到最后由于等待響應(yīng)被阻塞的客戶端越來(lái)越多,線程資源被耗費(fèi)完了。如下圖所示:

          Richardson-microservices-part3-threads-blocked-1024x383.png


          為了預(yù)防這種問題,設(shè)計(jì)服務(wù)時(shí)候必須要考慮部分失敗的問題。

          Netfilix提供了一個(gè)比較好的解決方案,具體的應(yīng)對(duì)措施包括:

          • 網(wǎng)絡(luò)超時(shí):當(dāng)?shù)却憫?yīng)時(shí),不要無(wú)限期的阻塞,而是采用超時(shí)策略。使用超時(shí)策略可以確保資源不會(huì)無(wú)限期的占用。
          • 限制請(qǐng)求的次數(shù):可以為客戶端對(duì)某特定服務(wù)的請(qǐng)求設(shè)置一個(gè)訪問上限。如果請(qǐng)求已達(dá)上限,就要立刻終止請(qǐng)求服務(wù)。
          • 斷路器模式(Circuit Breaker Pattern):記錄成功和失敗請(qǐng)求的數(shù)量。如果失效率超過一個(gè)閾值,觸發(fā)斷路器使得后續(xù)的請(qǐng)求立刻失敗。如果大量的請(qǐng)求失敗,就可能是這個(gè)服務(wù)不可用,再發(fā)請(qǐng)求也無(wú)意義。在一個(gè)失效期后,客戶端可以再試,如果成功,關(guān)閉此斷路器。
          • 提供回滾:當(dāng)一個(gè)請(qǐng)求失敗后可以進(jìn)行回滾邏輯。例如,返回緩存數(shù)據(jù)或者一個(gè)系統(tǒng)默認(rèn)值。

          Netflix Hystrix是一個(gè)實(shí)現(xiàn)相關(guān)模式的開源庫(kù)。如果使用JVM,推薦考慮使用Hystrix。而如果使用非JVM環(huán)境,你可以使用類似功能的庫(kù)。

          IPC技術(shù)

          現(xiàn)在有很多不同的IPC技術(shù)。服務(wù)之間的通信可以使用同步的請(qǐng)求/響應(yīng)模式,比如基于HTTP的REST或者Thrift。另外,也可以選擇異步的、基于消息的通信模式,比如AMQP或者STOMP。除以之外,還有其它的消息格式供選擇,比如JSON和XML,它們都是可讀的,基于文本的消息格式。當(dāng)然,也還有二進(jìn)制格式(效率更高)的,比如Avro和Protocol Buffer。接下來(lái)我們將會(huì)討論異步的IPC模式和同步的IPC模式,首先來(lái)看異步的。
          異步的,基于消息通信
          當(dāng)使用基于異步交換消息的進(jìn)程通信方式時(shí),一個(gè)客戶端通過向服務(wù)端發(fā)送消息提交請(qǐng)求。如果服務(wù)端需要回復(fù),則會(huì)發(fā)送另外一個(gè)獨(dú)立的消息給客戶端。因?yàn)橥ㄐ攀钱惒降模蛻舳瞬粫?huì)因?yàn)榈却枞喾矗蛻舳死硭?dāng)然的認(rèn)為響應(yīng)不會(huì)立刻接收到。

          一個(gè)消息由頭部(元數(shù)據(jù)例如發(fā)送方)和消息體構(gòu)成。消息通過channel發(fā)送,任何數(shù)量的生產(chǎn)者都可以發(fā)送消息到channel,同樣的,任何數(shù)量的消費(fèi)者都可以從渠道中接受數(shù)據(jù)。有兩類channel,點(diǎn)對(duì)點(diǎn)發(fā)布/訂閱。點(diǎn)對(duì)點(diǎn)channel會(huì)把消息準(zhǔn)確的發(fā)送到某個(gè)從channel讀取消息的消費(fèi)者,服務(wù)端使用點(diǎn)對(duì)點(diǎn)來(lái)實(shí)現(xiàn)之前提到的一對(duì)一交互模式;而發(fā)布/訂閱則把消息投送到所有從channel讀取數(shù)據(jù)的消費(fèi)者,服務(wù)端使用發(fā)布/訂閱channel來(lái)實(shí)現(xiàn)上面提到的一對(duì)多交互模式。

          下圖展示了打車軟件如何使用發(fā)布/訂閱:

          Richardson-microservices-part3-pub-sub-channels-1024x639.png


          行程管理服務(wù)在發(fā)布-訂閱channel內(nèi)創(chuàng)建一個(gè)行程消息,并通知調(diào)度服務(wù)有一個(gè)新的行程請(qǐng)求,調(diào)度服務(wù)發(fā)現(xiàn)一個(gè)可用的司機(jī)然后向發(fā)布-訂閱channel寫入司機(jī)建議消息(Driver Proposed message)來(lái)通知其他服務(wù)。

          有很多消息系統(tǒng)可以選擇,最好選擇一種支持多編程語(yǔ)言的。一些消息系統(tǒng)支持標(biāo)準(zhǔn)協(xié)議,例如AMQP和STOMP。其他消息系統(tǒng)則使用獨(dú)有的協(xié)議,有大量開源消息系統(tǒng)可選,比如RabbitMQApache KafkaApache ActiveMQNSQ。它們都支持某種形式的消息和channel,并且都是可靠的、高性能和可擴(kuò)展的;然而,它們的消息模型完全不同。

          使用消息機(jī)制有很多優(yōu)點(diǎn):

          • 解耦客戶端和服務(wù)端:客戶端只需要將消息發(fā)送到正確的channel。客戶端完全不需要了解具體的服務(wù)實(shí)例,更不需要一個(gè)發(fā)現(xiàn)機(jī)制來(lái)確定服務(wù)實(shí)例的位置。

          • Message Buffering:在一個(gè)同步請(qǐng)求/響應(yīng)協(xié)議中,例如HTTP,所有的客戶端和服務(wù)端必須在交互期間保持可用。而在消息模式中,消息broker將所有寫入channel的消息按照隊(duì)列方式管理,直到被消費(fèi)者處理。也就是說(shuō),在線商店可以接受客戶訂單,即使下單系統(tǒng)很慢或者不可用,只要保持下單消息進(jìn)入隊(duì)列就好了。

          • 彈性客戶端-服務(wù)端交互:消息機(jī)制支持以上說(shuō)的所有交互模式。

          • 直接進(jìn)程間通信:基于RPC機(jī)制,試圖喚醒遠(yuǎn)程服務(wù)看起來(lái)跟喚醒本地服務(wù)一樣。然而,因?yàn)槲锢矶珊筒糠质】赡苄裕麄儗?shí)際上非常不同。消息使得這些不同非常明確,開發(fā)者不會(huì)出現(xiàn)問題。

          然而,消息機(jī)制也有自己的缺點(diǎn):

          • 額外的操作復(fù)雜性:消息系統(tǒng)需要單獨(dú)安裝、配置和部署。消息broker(代理)必須高可用,否則系統(tǒng)可靠性將會(huì)受到影響。

          • 實(shí)現(xiàn)基于請(qǐng)求/響應(yīng)交互模式的復(fù)雜性:請(qǐng)求/響應(yīng)交互模式需要完成額外的工作。每個(gè)請(qǐng)求消息必須包含一個(gè)回復(fù)渠道ID和相關(guān)ID。服務(wù)端發(fā)送一個(gè)包含相關(guān)ID的響應(yīng)消息到channel中,使用相關(guān)ID來(lái)將響應(yīng)對(duì)應(yīng)到發(fā)出請(qǐng)求的客戶端。也許這個(gè)時(shí)候,使用一個(gè)直接支持請(qǐng)求/響應(yīng)的IPC機(jī)制會(huì)更容易些。

          現(xiàn)在我們已經(jīng)了解了基于消息的IPC,接下來(lái)我們來(lái)看看基于請(qǐng)求/響應(yīng)模式的IPC。

          同步的,基于請(qǐng)求/響應(yīng)的IPC
          當(dāng)使用一個(gè)同步的,基于請(qǐng)求/響應(yīng)的IPC機(jī)制,客戶端向服務(wù)端發(fā)送一個(gè)請(qǐng)求,服務(wù)端處理請(qǐng)求,返回響應(yīng)。一些客戶端會(huì)由于等待服務(wù)端響應(yīng)而被阻塞,而另外一些客戶端也可能使用異步的、基于事件驅(qū)動(dòng)的客戶端代碼(Future或者Rx Observable的封裝)。然而,不像使用消息機(jī)制,客戶端需要響應(yīng)及時(shí)返回。這個(gè)模式中有很多可選的協(xié)議,但最常見的兩個(gè)協(xié)議是REST和Thrift。首先我們來(lái)看下REST。

          REST

          現(xiàn)在很流行使用RESTful風(fēng)格的API。REST是基于HTTP協(xié)議的。另外,一個(gè)需要理解的比較重要的概念是,REST是一個(gè)資源,一般代表一個(gè)業(yè)務(wù)對(duì)象,比如一個(gè)客戶或者一個(gè)產(chǎn)品,或者一組商業(yè)對(duì)象。REST使用HTTP語(yǔ)法協(xié)議來(lái)修改資源,一般通過URL來(lái)實(shí)現(xiàn)。舉個(gè)例子,GET請(qǐng)求返回一個(gè)資源的簡(jiǎn)單信息,響應(yīng)格式通常是XML或者JSON對(duì)象格式。POST請(qǐng)求會(huì)創(chuàng)建一個(gè)新資源,PUT請(qǐng)求更新一個(gè)資源。這里引用下REST之父Roy Fielding說(shuō)的:

          當(dāng)需要一個(gè)整體的、重視模塊交互可擴(kuò)展性、接口概括性、組件部署獨(dú)立性和減小延遲、提供安全性和封裝性的系統(tǒng)時(shí),REST可以提供這樣一組滿足需求的架構(gòu)。
          下圖展示了打車軟件是如何使用REST的。

          Richardson-microservices-part3-rest-1024x397.png


          乘客通過移動(dòng)端向行程管理服務(wù)的/trips資源提交了一個(gè)POST請(qǐng)求。行程管理服務(wù)收到請(qǐng)求之后,會(huì)發(fā)送一個(gè)GET請(qǐng)求到乘客管理服務(wù)以獲取乘客信息。當(dāng)確認(rèn)乘客信息之后,緊接著會(huì)創(chuàng)建一個(gè)行程,并向移動(dòng)端返回201(譯者注:狀態(tài)碼)響應(yīng)。

          很多開發(fā)者都表示他們基于HTTP的API是RESTful的。但是,如同F(xiàn)ielding在他的博客中所說(shuō),這些API可能并不都是RESTful的。Leonard Richardson為REST定義了一個(gè)成熟度模型,具體包含以下4個(gè)層次(摘自IBM):
          • 第一個(gè)層次(Level 0)的 Web 服務(wù)只是使用 HTTP 作為傳輸方式,實(shí)際上只是遠(yuǎn)程方法調(diào)用(RPC)的一種具體形式。SOAP 和 XML-RPC 都屬于此類。
          • 第二個(gè)層次(Level 1)的 Web 服務(wù)引入了資源的概念。每個(gè)資源有對(duì)應(yīng)的標(biāo)識(shí)符和表達(dá)。
          • 第三個(gè)層次(Level 2)的 Web 服務(wù)使用不同的 HTTP 方法來(lái)進(jìn)行不同的操作,并且使用 HTTP 狀態(tài)碼來(lái)表示不同的結(jié)果。如 HTTP GET 方法來(lái)獲取資源,HTTP DELETE 方法來(lái)刪除資源。
          • 第四個(gè)層次(Level 3)的 Web 服務(wù)使用 HATEOAS。在資源的表達(dá)中包含了鏈接信息。客戶端可以根據(jù)鏈接來(lái)發(fā)現(xiàn)可以執(zhí)行的動(dòng)作。

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

          • HTTP非常簡(jiǎn)單并且大家都很熟悉。
          • 可以使用瀏覽器擴(kuò)展(比如Postman)或者curl之類的命令行來(lái)測(cè)試API。
          • 內(nèi)置支持請(qǐng)求/響應(yīng)模式的通信。
          • HTTP對(duì)防火墻友好的。
          • 不需要中間代理,簡(jiǎn)化了系統(tǒng)架構(gòu)。

          不足之處包括:

          • 只支持請(qǐng)求/響應(yīng)模式交互。可以使用HTTP通知,但是服務(wù)端必須一直發(fā)送HTTP響應(yīng)才行。
          • 因?yàn)榭蛻舳撕头?wù)端直接通信(沒有代理或者buffer機(jī)制),在交互期間必須都在線。
          • 客戶端必須知道每個(gè)服務(wù)實(shí)例的URL。如之前那篇關(guān)于API Gateway的文章所述,這也是個(gè)煩人的問題。客戶端必須使用服務(wù)實(shí)例發(fā)現(xiàn)機(jī)制。

          開發(fā)者社區(qū)最近重新發(fā)現(xiàn)了RESTful API接口定義語(yǔ)言的價(jià)值。于是就有了一些RESTful風(fēng)格的服務(wù)框架,包括RAMLSwagger。一些IDL,例如Swagger允許定義請(qǐng)求和響應(yīng)消息的格式。其它的,例如RAML,需要使用另外的標(biāo)識(shí),例如JSON Schema。對(duì)于描述API,IDL一般都有工具來(lái)定義客戶端和服務(wù)端骨架接口。

          Thrift

          Apache Thrift是一個(gè)很有趣的REST的替代品。它是Facebook實(shí)現(xiàn)的一種高效的、支持多種編程語(yǔ)言的遠(yuǎn)程服務(wù)調(diào)用的框架。Thrift提供了一個(gè)C風(fēng)格的IDL定義API。使用Thrift編譯器可以生成客戶端和服務(wù)器端代碼框架。編譯器可以生成多種語(yǔ)言的代碼,包括C++、Java、Python、PHP、Ruby, Erlang和Node.js。

          Thrift接口包括一個(gè)或者多個(gè)服務(wù)。服務(wù)定義類似于一個(gè)JAVA接口,是一組方法。Thrift方法可以返回響應(yīng),也可以被定義為單向的。返回值的方法其實(shí)就是請(qǐng)求/響應(yīng)類型交互模式的實(shí)現(xiàn)。客戶端等待響應(yīng),并可能拋出異常。單向方法對(duì)應(yīng)于通知類型的交互模式,服務(wù)端并不返回響應(yīng)。

          Thrift支持多種消息格式:JSON、二進(jìn)制和壓縮二進(jìn)制。二進(jìn)制比JSON更高效,因?yàn)槎M(jìn)制解碼更快。同樣原因,壓縮二進(jìn)制格式可以提供更高級(jí)別的壓縮效率。JSON,是易讀的。Thrift也可以在裸TCP和HTTP中間選擇,裸TCP看起來(lái)比HTTP更加有效。然而,HTTP對(duì)防火墻,瀏覽器和人來(lái)說(shuō)更加友好。
          消息格式
          了解完HTTP和Thrift后,我們來(lái)看下消息格式方面的問題。如果使用消息系統(tǒng)或者REST,就可以選擇消息格式。其它的IPC機(jī)制,例如Thrift可能只支持部分消息格式,也許只有一種。無(wú)論哪種方式,我們必須使用一個(gè)跨語(yǔ)言的消息格式,這非常重要。因?yàn)橹覆欢奶炷銜?huì)使用其它語(yǔ)言。

          有兩類消息格式:文本和二進(jìn)制。文本格式的例子包括JSON和XML。這種格式的優(yōu)點(diǎn)在于不僅可讀,而且是自描述的。在JSON中,一個(gè)對(duì)象就是一組鍵值對(duì)。類似的,在XML中,屬性是由名字和值構(gòu)成。消費(fèi)者可以從中選擇感興趣的元素而忽略其它部分。同時(shí),小幅度的格式修改可以很容器向后兼容。

          XML文檔結(jié)構(gòu)是由XML schema定義的。隨著時(shí)間發(fā)展,開發(fā)者社區(qū)意識(shí)到JSON也需要一個(gè)類似的機(jī)制。一個(gè)選擇是使用JSON Schema,要么是獨(dú)立的,要么是例如Swagger的IDL。

          基于文本的消息格式最大的缺點(diǎn)是消息會(huì)變得冗長(zhǎng),特別是XML。因?yàn)橄⑹亲悦枋龅模悦總€(gè)消息都包含屬性和值。另外一個(gè)缺點(diǎn)是解析文本的負(fù)擔(dān)過大。所以,你可能需要考慮使用二進(jìn)制格式。

          二進(jìn)制的格式也有很多。如果使用的是Thrift RPC,那可以使用二進(jìn)制Thrift。如果選擇消息格式,常用的還包括Protocol BuffersApache Avro。它們都提供典型的IDL來(lái)定義消息架構(gòu)。一個(gè)不同點(diǎn)在于Protocol Buffers使用的是加標(biāo)記(tag)的字段,而Avro消費(fèi)者需要知道模式(schema)來(lái)解析消息。因此,使用前者,API更容易演進(jìn)。這篇博客很好的比較了Thrift、Protocol Buffers、Avro三者的區(qū)別。

          總結(jié)

          微服務(wù)必須使用進(jìn)程間通信機(jī)制來(lái)交互。當(dāng)設(shè)計(jì)服務(wù)的通信模式時(shí),你需要考慮幾個(gè)問題:服務(wù)如何交互,每個(gè)服務(wù)如何標(biāo)識(shí)API,如何升級(jí)API,以及如何處理部分失敗。微服務(wù)架構(gòu)有兩類IPC機(jī)制可選,異步消息機(jī)制和同步請(qǐng)求/響應(yīng)機(jī)制。在下一篇文章中,我們將會(huì)討論微服務(wù)架構(gòu)中的服務(wù)發(fā)現(xiàn)問題。

          原文鏈接:Building Microservices: Inter-Process Communication in a Microservices Architecture(翻譯:楊峰 校對(duì):李穎杰)

          posted on 2016-03-17 18:05 一杯清茶 閱讀(137) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 怀仁县| 托克托县| 靖州| 密山市| 平和县| 山阴县| 南投县| 栾川县| 西青区| 宁安市| 新余市| 延吉市| 海丰县| 阳西县| 洪江市| 高青县| 长丰县| 邳州市| 敖汉旗| 德令哈市| 准格尔旗| 台南县| 恩施市| 廊坊市| 镇巴县| 永修县| 新疆| 彭水| 柳州市| 库伦旗| 越西县| 客服| 新乡市| 循化| 剑阁县| 文山县| 财经| 和政县| 陵川县| 房产| 方正县|