在微服務架構中,可能會有幾十甚至上百個微服務。在對外提供的某一項功能中,可能須要同時或依次調用這些服務。所以保證微服務之間通訊的穩定性是十分必要的。數據庫
彈性安全
網絡通訊可能會失敗網絡
一個服務實例會因爲各類各樣的緣由致使異常,多是部署實例節點異常,多是硬件異常,多是網絡的不穩定,也有多是服務自己的異常。架構
解決方法負載均衡
重試異步
正如字面意思表達的那樣,若是調用某個服務接口失敗了,能夠再次向該接口發起請求。但這裏要注意的是,連續向同一失敗的服務發起請求可能反而會加重該服務所在實例的壓力,全部的請求都佔用了一部分CPU、內存以及數據庫鏈接,最終致使實例的崩潰。常見的方案是限制重試的次數,或是增長重試之間的時間間隔。分佈式
熔斷微服務
老式的電路中每每會有保險絲保護整個電路系統(現代電路中常見的是空氣開關,但整體設計思路是一致的),一旦電流過大,保險絲溫度升高達到熔點,保險絲熔斷,致使整個電路斷路,從而保護用電器安全。在API網關中也能夠實現一個相似保險絲的開關,一旦檢測到某個服務的壓力過大,便可適時阻止繼續向該服務發起請求,直到服務恢復正常。加密
負載均衡設計
爲了保證服務的可用性,同一個服務每每會同時部署在多個服務上,爲了均衡每一個實例的請求壓力,咱們須要一個負載均衡方案。
分佈式追蹤
儘管每一項服務都會記錄本身的日誌,但若是不把這些日誌聚合在一塊兒,其實也很難利用這些單獨的日誌分析問題。
服務版本
每當你部署新版本的服務時,你都得確保不會由於其餘服務仍然在調用你的舊版本接口而致使異常。甚至有的時候你可能想同時提供多個版本的服務。
TSL加密和TLS鑑權
對於成熟的服務來講,通信加密和鑑權是必不可少的安全環節。
服務間的通訊常見有兩種方式:一種是更易於理解的同步消息,調用方會同步等待服務返回結果。另外一種是異步消息隊列如RabbitMQ、Kafka等中間件,咱們只須要將消息發送給消息中間件,不須要等待服務返回結果。
下降耦合
因爲調用方把請求發送給消息中間件,而不是直接調用服務,所以每一個服務之間能夠徹底獨立。
多重訂閱
利用消息中間件咱們能夠實現發佈訂閱模式,多個服務能夠同時訂閱某一個消息。好比用戶下單消息可能同時須要支付服務,庫存服務,訂單服務訂閱消息。
錯誤隔離
因爲調用方再也不同步等待請求返回結果,所以即便服務發生異常,也不須要調用方處理。
響應度
因爲調用方再也不同步等待請求返回結果,所以調用方發送消息成功後便可立刻返回客戶端,下降響應時間。
負載管理
消息中間件做爲承載消息的管道,徹底能夠做爲服務的緩衝池,即便消息產生的速度再快,服務方也能夠徹底按照本身的處理速率處理消息。
工做流
消息中間件能夠在工做流的每個步驟間設置檢查點,管理工做流的流向,處理結果。
消息中間件耦合
雖然調用方再也不與服務方耦合,然而調用方和服務方卻都和消息中間件耦合在一塊兒。
延遲
若是消息堆積在消息中間件,整個端到端的服務延遲必然會增長。
費用
在消息處理速率不斷增加的同時,可能也會帶來服務成本的不斷提升,尤爲是當你使用雲服務廠商提供的消息中間件服務時。
複雜度
引入更多的中間件必然帶來整個架構複雜度的加深
重複消息
消除重複消息
冪等操做
請求響應語義[1]
須要另外一個消息隊列
協同請求和響應消息
吞吐
隊列語義[1]成爲處理異步消息的瓶頸
至少須要一次入隊操做
至少須要一次出隊操做
隊列基礎設施中每每須要某種鎖才能實現隊列語義
若是使用的是雲廠商提供的隊列服務的話,更是增長了網絡通訊的延遲
有時甚至包含複雜的批處理消息
能夠考慮使用事件流代替隊列
[1]: 隊列語義
消費語義
最多消費一次
最少消費一次
剛好消費一次
投遞語義
最多投遞一次
最少投遞一次
剛好投遞一次