在微服務架構中,可能會有幾十甚至上百個微服務,在對外提供的某一項功能中,可能需要同時或依次呼叫這些服務,因此保證微服務之間通信的穩定性是十分必要的,
難點
-
彈性
-
網路通信可能會失敗
一個服務實體會由于各種各樣的原因導致例外,可能是部署實體節點例外,可能是硬體例外,可能是網路的不穩定,也有可能是服務本身的例外,
-
解決方法
-
重試
正如字面意思表達的那樣,如果呼叫某個服務介面失敗了,可以再次向該介面發起請求,但這里要注意的是,連續向同一失敗的服務發起請求可能反而會加劇該服務所在實體的壓力,所有的請求都占用了一部分CPU、記憶體以及資料庫連接,最終導致實體的崩潰,常見的方案是限制重試的次數,或是增加重試之間的時間間隔,
-
熔斷
老式的電路中往往會有保險絲保護整個電路系統(現代電路中常見的是空氣開關,但總體設計思路是一致的),一旦電流過大,保險絲溫度升高達到熔點,保險絲熔斷,導致整個電路斷路,從而保護用電器安全,在API網關中也可以實作一個類似保險絲的開關,一旦檢測到某個服務的壓力過大,即可適時阻止繼續向該服務發起請求,直到服務恢復正常,
-
負載均衡
為了保證服務的可用性,同一個服務往往會同時部署在多個服務上,為了均衡每個實體的請求壓力,我們需要一個負載均衡方案,
-
分布式追蹤
盡管每一項服務都會記錄自己的日志,但如果不把這些日志聚合在一起,其實也很難利用這些單獨的日志分析問題,
-
服務版本
每當你部署新版本的服務時,你都得確保不會因為其他服務仍然在呼叫你的舊版本介面而導致例外,甚至有的時候你可能想同時提供多個版本的服務,
-
TSL加密和TLS鑒權
對于成熟的服務來說,通訊加密和鑒權是必不可少的安全環節,
服務間的通信常見有兩種方式:一種是更易于理解的同步訊息,呼叫方會同步等待服務回傳結果,另一種是異步訊息佇列如RabbitMQ、Kafka等中間件,我們只需要將訊息發送給訊息中間件,不需要等待服務回傳結果,
異步訊息
優勢
-
降低耦合
由于呼叫方把請求發送給訊息中間件,而不是直接呼叫服務,因此每個服務之間可以完全獨立,
-
多重訂閱
利用訊息中間件我們可以實作發布訂閱模式,多個服務可以同時訂閱某一個訊息,比如用戶下單訊息可能同時需要支付服務,庫存服務,訂單服務訂閱訊息,
-
錯誤隔離
由于呼叫方不再同步等待請求回傳結果,因此即使服務發生例外,也不需要呼叫方處理,
-
回應度
由于呼叫方不再同步等待請求回傳結果,因此呼叫方發送訊息成功后即可馬上回傳客戶端,降低回應時間,
-
負載管理
訊息中間件作為承載訊息的管道,完全可以作為服務的緩沖池,即使訊息產生的速度再快,服務方也可以完全按照自己的處理速率處理訊息,
-
作業流
訊息中間件可以在作業流的每一個步驟間設定檢查點,管理作業流的流向,處理結果,
難點
-
訊息中間件耦合
雖然呼叫方不再與服務方耦合,然而呼叫方和服務方卻都和訊息中間件耦合在一起,
-
延遲
如果訊息堆積在訊息中間件,整個端到端的服務延遲必然會增加,
-
費用
在訊息處理速率不斷增長的同時,可能也會帶來服務成本的不斷提高,尤其是當你使用云服務廠商提供的訊息中間件服務時,
-
復雜度
引入更多的中間件必然帶來整個架構復雜度的加深
-
重復訊息
-
消除重復訊息
-
冪等操作
-
請求回應語意[1]
-
需要另一個訊息佇列
-
協同請求和回應訊息
-
吞吐
-
佇列語意[1]成為處理異步訊息的瓶頸
-
至少需要一次入隊操作
-
至少需要一次出隊操作
-
佇列基礎設施中往往需要某種鎖才能實作佇列語意
-
如果使用的是云廠商提供的佇列服務的話,更是增加了網路通信的延遲
-
有時甚至包含復雜的批處理訊息
-
可以考慮使用事件流代替佇列
[1]: 佇列語意
-
消費語意
-
最多消費一次
-
最少消費一次
-
恰好消費一次
-
投遞語意
-
最多投遞一次
-
最少投遞一次
-
恰好投遞一次
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/265083.html
標籤:其他
