詳解微服務編排

詳解微服務編排

譯者 | 塗承燁

你的組織是否使用微服務風格的體系結構來實現其業務功能?你使用什麼方法來實現微服務的通訊和編排?在過去的幾年中,微服務一直是一個相當占主導地位的應用程式架構,通常與雲平臺(例如,容器、K8s、FaaS(功能即服務)、臨時雲服務)結合在一起使用。這些服務型別之間的通訊模式差別很大。

微服務體系結構強調獨立性和頻繁更改的能力,但這些服務通常需要共享資料,並在它們之間發起複雜的互動,以完成它們的功能。在本文中,我們將研究微服務通訊的模式和策略。

一、網路中的問題

透過網路進行通訊會帶來可靠性問題。資料包可能被丟棄、延遲或重複,所有這些都可能導致服務到服務通訊的異常和不可靠。在最基本的情況下-服務A開啟到服務B的連線-我們非常信任應用程式庫和網路本身,以開啟連線並向目標服務(在本例中是服務B)傳送請求。

詳解微服務編排

圖1:服務A呼叫服務B的簡單示例

但如果連線需要很長時間才能開啟,會發生什麼呢?如果連線超時無法開啟該怎麼辦?如果連線成功,但隨後在處理請求之後、響應之前關閉該連線怎麼辦?

我們需要一種快速檢測連線或請求問題並決定如何處理的方法。如果服務A無法與服務B通訊,可能會有一些合理的返回(如,返回錯誤訊息、響應固定內容、使用快取值進行響應)。

詳解微服務編排

圖2:呼叫多個服務的更復雜的示例

在稍微複雜一些的情況下,服務A可能需要呼叫服務B,從服務B的響應中檢索一些值,然後使用它呼叫服務C。如果對服務B的呼叫成功,但對服務C的呼叫失敗,那麼返回選項可能會稍微複雜一些。

也許我們可以回退到一個預定義的響應,重試請求,根據服務B響應的一些資料從快取中提取資料,或者呼叫一個不同的服務?

網路中導致連線或請求失敗的問題可能會間歇性地發生,應用程式必須處理這些問題。

隨著從給定服務編排的服務呼叫越多,這些問題就越有可能發生,也越複雜,如圖3所示。

詳解微服務編排

圖3:嘗試編排跨讀/寫API的多個服務呼叫示例

當這些服務間的呼叫不僅僅是“讀”呼叫時,這些問題將變得更加麻煩。

例如,如果服務A呼叫服務B,服務B執行某種必須與下一次對服務C的呼叫需使用的資料變更(例如,服務A告訴服務B客戶Joe的地址已更新,但還必須告訴服務C由於地址更改而更改運輸),那麼這些失敗的呼叫是重要的。

這可能會導致不同服務之間的資料不一致和狀態不一致。

這樣的網路錯誤會影響微服務的彈性、資料一致性以及可能的服務級別目標(SLOs)和服務級別協議(SLAs)。

我們需要一種方法來處理這些網路問題,同時考慮在嘗試解釋故障時突然出現的其他問題。

二、有用的網路彈性模式

構建API和服務來抵禦網路的不可靠性並不總是那麼容易。服務(包括用於構建服務的框架和庫)可能會因為網路而失敗,有時會以不可預測的方式發生。這裡介紹了一些有助於構建彈性服務通訊的模式,但肯定不是唯一的模式。

這三種模式可以根據需要使用,也可以結合使用來提高通訊的可靠性(但每種模式都有自己的缺點):

重試/回退重試-如果呼叫失敗,重新發送請求,可能會等待一段時間再嘗試。

冪等請求處理-對一個請求進行多次處理並得到相同結果的能力(可能涉及對寫操作的重複刪除處理)。

非同步請求處理-消除兩個服務之間的時間耦合,以確保請求傳遞成功。

讓我們來仔細看看這些模式。

三、具有回退處理的重試

網路的不可靠性隨時可能發生,如果請求失敗或無法建立連線,最簡單的方法之一就是重試。通常,我們需要某種有限的重試次數(例如,“重試兩次”VS“無限重試”),並且可能需要一種回退重試的方法。

有了回退機制,我們可以錯開呼叫失敗和重試所花費的時間。

關於重試的一個簡短說明:我們不能永遠重試,也不能將每個服務配置為重試相同次數。重試可能會對“重試風暴”事件產生負面影響,在這些事件中,服務降級,呼叫服務多次重試,從而對降級的服務施加壓力,並最終關閉(或在嘗試恢復時將其關閉)。一開始可以在呼叫鏈的較高位置使用少量固定的重試次數(例如,兩次),並且不要在呼叫鏈的較深處重試。

四、冪等請求處理

對於基於傳入請求對資料進行更改的服務,服務提供者實現冪等請求處理。一個簡單的例子是計數器服務,它保持執行的總計數,並根據傳入的請求增加計數。

例如,可能傳入一個值為“5”的請求,計數器服務將使當前計數增加5。但是,如果服務處理請求(以5為增量),但不知何故返回給客戶機的響應丟失了(網路丟包、連線失敗等),該怎麼辦?

客戶端可能會重試請求,但這將使計數再次增加5,而這可能不是所希望的狀態。我們希望服務知道它已經看到了一個特定的請求,然後要麼忽略它,要麼應用一個“no-op”。如果服務被構建為冪等處理請求,那麼客戶機可以放心地重試失敗的請求,因為服務能夠過濾掉那些重複的請求。

五、非同步請求處理

對於前面示例中的服務互動,我們已經假設了某種型別的請求/響應互動,但是我們可以透過依賴某種佇列或日誌機制來在傳遞中持久化訊息並將其交付給使用者,從而減輕網路的一些麻煩。在這個模型中,我們去掉了請求的傳送方和接收方在同一時間同時可用的可能性。

我們可以信任訊息日誌或佇列在未來的某個時刻儲存和傳遞訊息。重試和冪等請求處理也適用於非同步場景。如果訊息使用者能夠正確地應用可能在“至少一次交付”保證中發生的更改,那麼我們就不需要更復雜的事務協調。

六、服務到服務通訊的基本工具和考慮事項

為了將彈性構建到服務到服務的通訊中,團隊可能依賴於額外的平臺基礎設施,例如,像Kafka這樣的非同步訊息日誌或像Istio服務網格這樣的微服務彈性框架。可以對具有服務網格的應用程式透明地配置和執行諸如重試、斷路和超時等任務。因為你可以從外部控制和配置行為,所以這些行為可以應用於任何/所有應用程式—無論它們是用什麼程式語言編寫的。此外,可以對這些彈性策略進行快速更改,而無需強制程式碼更改。

在微服務體系結構中,幫助進行服務編排的另一個工具是GraphQL引擎。GraphQL引擎允許團隊跨多個服務展開和編排服務呼叫,同時負責身份驗證、授權、快取和其他訪問機制。GraphQL還允許團隊更多地關注特定客戶端或服務呼叫的資料元素。GraphQL最初主要用於表示層客戶端(Web、移動端等),但現在也越來越多地用於服務到服務的API呼叫。

詳解微服務編排

圖4:使用GraphQL引擎編排跨多個服務的服務呼叫

如上所述,GraphQL還可以與API 閘道器技術甚至服務網格技術相結合。不管服務之間使用什麼協議進行通訊(REST、gRPC、GraphQL等),這些都可以提供一個通用且一致的彈性策略層。

七、結論

大多數團隊都希望透過雲基礎設施和微服務架構來實現圍繞服務交付和規模的重大承諾。我們可以建立CI/CD、容器平臺和一個強大的服務架構,但如果我們不考慮執行時微服務編排和隨之而來的彈性挑戰,那麼微服務實際上只是一個過於複雜的部署架構,具有所有的缺點,沒有任何好處。如果你正在使用微服務的路上(或者已經在這條路上走得很好了),請確保服務通訊、編排、安全性和可觀察性被放在首位,並在你的服務中一致地實現。

原文連結:https://dzone。com/articles/microservices-orchestration

譯者介紹:

塗承燁,51CTO社群編輯,資訊系統專案管理師、資訊系統監理師、PMP,某省綜合性評標專家,擁有15年的開發經驗。目前就職於壹體技術有限公司,從事較大型專案管理工作。