1. 程式人生 > >[譯] 微服務的設計模式

[譯] 微服務的設計模式

瞭解微服務架構的設計模式以克服採用它所帶來的挑戰。

微服務架構已經成為現代應用程式開發中公認的技術選擇。儘管它解決了某些問題,但不是靈丹妙藥。它有幾個缺點,使用這種體系架構時,還需要解決許多問題。這就需要學習這些問題的通用模式,並通過可重用的解決方案來解決它們。因此,有必要討論微服務的設計模式。在深入研究設計模式之前,我們需要了解微服務架構的構建原理:
1.可擴充套件性
2.可用性
3.彈性
4.獨立自治性
5.去中心化治理
6.失敗隔離
7.自動配置
8.通過DevOps持續交付

應用所有這些原則會帶來一些挑戰和問題。讓我們討論這些問題及其解決方案。


分解模式

按業務能力分解

問題

微服務就是要應用單一責任原則使服務鬆散耦合。但是,將應用程式分成較小的部分必須在邏輯上完成。那麼,我們如何將應用程式分解為小型服務呢?

解決

一種策略是按業務能力分解。所謂業務能力就是可以體現企業業務價值的,給定業務的功能集取決於業務型別。例如,保險公司的功能通常包括銷售,市場營銷,承保,理賠處理,計費,合規性等。每個業務功能都可以視為一種服務,但它是面向業務的,而不是技術的。

按子域分解

問題

使用業務功能分解應用程式可能是一個不錯的開始,但是您會遇到所謂的“神類”,這些類將不容易分解。它們將在多種服務中通用。例如,訂單類將用於“訂單管理”,“接單”,“訂單交付”等業務中。我們該如何分解它們?

解決

對於“神類”問題,DDD(領域驅動設計)可以解決。它使用子域和有界上下文概念來解決此問題。DDD將為企業建立的整個域模型分解為子域。每個子域都有一個模型,該模型的範圍稱為有界上下文。每個微服務將圍繞有界的上下文進行開發。

注意:確定子域並非易事。它需要對業務的瞭解。像業務功能一樣,通過分析業務及其組織結構並確定不同的專業領域來標識子域。

扼殺模式

問題

到目前為止,我們討論的設計模式都是分解未開發的應用程式,但是我們所做的工作中有80%是用於棕色的應用程式,這是大型的整體應用程式。將上述所有設計模式應用於它們將很困難,因為把他們當作一個整體應用的同時將它們拆分成一個個較小的部分是一項艱鉅的任務。

解決

扼殺者模式可以解決此類問題。扼殺者模式是基於藤蔓纏繞植物的類比。此解決方案與Web應用程式配合使用,在Web應用程式之間來回呼叫,對於每個URI呼叫,服務可以分為不同的域並作為單獨的服務託管。這個想法是一次做一個域。這將建立兩個單獨的應用程式,它們在同一URI空間中並排執行。最終,新重構的應用程式會“扼殺”或替換原始應用程式,直到最終您可以關閉整體應用程式。

整合模式

api閘道器

問題

當一個應用被分解為多個微服務時,還會有一些問題需要解決。

1.如何呼叫多個微服務來抽象生產者資訊。

2.在不同的渠道(例如桌上型電腦,移動裝置和平板電腦)上,由於UI可能不同,應用程式需要不同的資料來響應相同的後端服務。

3.不同的使用者對於可重複使用的微服務響應格式可能不同。誰將進行資料轉換或現場操作?

4.生產者微服務可能不支援某些型別協議的處理方式。

解決

API閘道器有助於解決微服務實現引起的許多問題,而不僅限於上述問題。

1.API閘道器是任何微服務呼叫的單一入口點。

2.它可以用作代理服務,以將請求路由到相關的微服務,從而抽象出生產者詳細資訊。

3.它可以將對多個服務的請求散發出去,然後彙總結果以傳送回消費者。

4.千篇一律的所有API不能解決所有消費者的需求;該解決方案可以為每種特定型別的客戶端建立一個細粒度的API。

5.它還可以將協議請求(例如AMQP)轉換為另一個協議(例如HTTP),反之亦然,以便生產者和消費者可以處理它。

6.它還可以減輕微服務的身份驗證/授權責任。

聚合器

問題

我們已經討論瞭解決API閘道器模式中的聚合資料問題。但是,我們將在這裡全面討論它。
將業務功能分解為幾個較小的邏輯程式碼段時,有必要考慮如何聚合每個服務返回的資料。消費者不能承擔此責任,因為這可能需要了解生產者應用程式的內部實現。

解決

聚集器模式有助於解決此問題。它討論瞭如何聚合來自不同服務的資料,然後將最終響應傳送給消費者。這可以通過兩種方式完成:

1.複合微服務將呼叫所有必需的微服務,合併資料,並在傳送回資料之前對其進行轉換。

2.API閘道器還可以將請求劃分為多個微服務並聚合資料,然後再將其傳送給使用者。

如果要應用任何業務邏輯,建議選擇複合微服務。否則,API閘道器是已建立的解決方案。

客戶端UI組合

問題

通過分解業務功能/子域來開發服務時,負責使用者體驗的服務必須從多個微服務中提取資料。在整體應用中,從UI到後端服務只有一次呼叫,以檢索所有資料並重新整理/提交UI頁面。但是,現在不一樣了。我們需要了解如何去做。

解決

對於微服務,必須將UI設計為具有螢幕/頁面的多個部分/區域的框架。每個部分都將呼叫單個後端微服務以提取資料。這稱為組成特定於服務的UI元件。諸如AngularJS和ReactJS之類的框架可以輕鬆地做到這一點。這些螢幕稱為單頁應用程式(SPA)。這使應用程式可以重新整理螢幕的特定區域而不是重新整理整個頁面。

資料庫模式

每個服務一個數據庫

問題

如何定義微服務的資料庫體系結構存在一個問題。以下是要解決的問題:

1.服務必須鬆散耦合。它們可以獨立開發,部署和擴充套件。

2.業務事務可能會強制跨越多個服務的不變數。

3.一些業務事務需要查詢多個服務擁有的資料。

4.有時必須複製資料庫並對其進行分片以進行擴充套件。

5.不同的服務具有不同的資料儲存要求。

解決

為了解決上述問題,必須為每個微服務設計一個數據庫。它必須僅對該服務專用。只能由微服務API訪問它。其他服務無法直接訪問它。例如,對於關係資料庫,我們可以使用每個服務一個專用表,每個服務一個schema或每個服務一個數據庫伺服器。每個微服務應具有一個單獨的資料庫ID,以便可以給予單獨的訪問許可權以設定障礙並防止其使用其他服務表。

每個服務共享資料庫

問題

我們已經討論了每個服務一個數據庫是微服務的理想選擇,當應用程式是未開發的並且要使用DDD開發時,這是可能的。但是,如果應用程式是一個整體並且試圖闖入微服務,那麼非規範化就不那麼容易了。在那種情況下合適的架構是什麼?

解決

每個服務共享資料庫不是理想的選擇,但這是上述情況的可行解決方案。大多數人認為這是微服務的反模式,但對於棕色應用程式來說,這是將應用程式分解成較小邏輯部分的一個很好的開始。這不適用於未開發的應用程式。在這種模式下,一個數據庫可以與一個以上的微服務對齊,但是必須限制為最大2-3個微服務,否則伸縮,自治和獨立性將難以執行。

命令查詢職責隔離(CQRS)

問題

一旦我們實現了每個服務的資料庫,就需要進行查詢,這需要來自多個服務的聯合資料-這是不可能的。那麼,我們如何在微服務架構中實現查詢?

解決

CQRS建議將應用程式分為兩部分-命令端和查詢端。命令列處理建立,更新和刪除請求。查詢端通過使用例項化檢視來處理查詢部分。通常將事件源模式與它一起使用來為任何資料更改建立事件。通過訂閱事件流,可以使例項化檢視保持更新。

saga模式

問題

當每個服務都有自己的資料庫並且一個業務事務跨越多個服務時,我們如何確保各個服務之間的資料一致性?例如,對於客戶有信用額度的電子商務應用程式,該應用程式必須確保新訂單不會超過客戶的信用額度。由於訂單和客戶位於不同的資料庫中,因此應用程式不能簡單地使用本地ACID事務。

解決

Saga代表由幾個子請求組成的高階業務流程,每個子請求在單個服務中更新資料。每個請求都有一個補償請求,該請求在請求失敗時執行。它可以通過兩種方式實現:

1.Choreography-如果沒有中央協調,則每個服務都會產生並偵聽另一個服務的事件,並決定是否應採取措施。
2.Orchestration-協調員(物件)負責傳奇的決策和業務邏輯排序。

可觀察性模式

日誌彙總

問題

考慮一個用例,其中一個應用程式由在多臺計算機上執行的多個服務例項組成。請求通常跨越多個服務例項。每個服務例項均以標準化格式生成日誌檔案。我們如何通過日誌瞭解特定請求的應用程式行為?

解決

我們需要一個集中式日誌記錄服務,該服務可以彙總每個服務例項的日誌。使用者可以搜尋和分析日誌。他們可以配置在某些訊息出現在日誌中時觸發的警報。例如,PCF確實具有Loggeregator,它從PCF平臺的每個元件(路由器,控制器,diego等)收集日誌,並附帶應用程式。 AWS Cloud Watch也這樣做。

效能指標

問題

當服務組合由於微服務架構而增加時,密切關注事務至關重要,以便可以監控模式並在發生問題時傳送警報。我們應該如何收集指標以監視應用程式效能?

解決

需要度量服務來收集有關單個操作的統計資訊。它應該聚合提供報告和警報的應用程式服務的指標。有兩種用於彙總指標的模型:

1.推送-服務將指標推送到指標服務,例如NewRelic,AppDynamics

2.提取-指標服務從服務中提取指標,例如普羅米修斯

分散式跟蹤

問題

在微服務架構中,請求通常跨越多個服務。每個服務通過跨多個服務執行一個或多個操作來處​​理請求。然後,我們如何跟蹤端到端的請求以解決問題?

解決

我們需要一項服務