絞殺無花果圖案 - AWS 規定指引

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

絞殺無花果圖案

意圖

扼殺程式圖案可協助逐步將整合式應用程式移轉至微服務架構,同時降低轉型風險和業務中斷。

动机

單片應用程序的開發是為了在單個進程或容器中提供其大部分功能。代碼緊密耦合。因此,應用程式變更需要徹底的重新測試,以避免回歸問題。這些變更無法單獨測試,這會影響週期時間。由於該應用程序具有更多功能,因此高複雜性可能會導致更多的時間花在維護上,增加上市時間,從而減慢產品創新。

當應用程式縮放大小時,它會增加團隊的認知負載,並可能導致不清楚的團隊擁有權界限。無法根據負載縮放個別功能,因此必須調整整個應用程式以支援尖峰負載。隨著系統老化,該技術可能會過時,從而增加了支持成本。整體式舊版應用程式遵循開發時所提供的最佳做法,而不是設計用來散佈。

當整合式應用程式移轉至微服務架構時,它可以分割成較小的元件。這些元件可以獨立調整,可以獨立發行,並且可以由個別團隊擁有。這會導致更快的變更速度,因為變更已本地化,並且可以快速測試和發行。變更的影響範圍較小,因為元件是鬆散耦合的,而且可以個別部署。

通過重寫或重構代碼來完全用微服務應用程序替換整體式是一項巨大的任務,也是一個很大的風險。一場巨大爆炸的遷移,在單一作業中遷移整體式,引入了轉型風險和業務中斷。在重構應用程序時,添加新功能非常困難甚至不可能。

解決此問題的一種方法是使用馬丁·福勒(Martin Fowler)引入的絞殺程序無花果圖案。此模式涉及通過逐步提取功能並圍繞現有系統創建新的應用程序來轉移到微服務。整體式中的功能逐漸被微服務取代,應用程式使用者可以逐步使用新移轉的功能。當所有功能都移出到新系統時,可以安全地解除委任整合式應用程式。

適用性

在以下情況下使用絞殺器圖案:

  • 您想要逐步將整合式應用程式遷移到微服務架構。

  • 由於整體的規模和複雜性,大爆炸遷移方法是有風險的。

  • 企業想要添加新功能,不能等待轉型完成。

  • 在轉換期間,最終使用者必須受到最小的影響。

問題和考慮因素

  • 代碼庫訪問:要實現扼殺程序 fig 模式,您必須可以訪問整體應用程序的代碼庫。隨著功能從整體移轉出來,您將需要進行次要的程式碼變更,並在整體式中實作反腐敗層,以將呼叫路由到新的微服務。如果沒有程式碼庫存取權,就無法攔截呼叫。程式碼庫存取對於重新導向傳入要求也很重要,可能需要一些程式碼重構,以便 Proxy 層可攔截已移轉功能的呼叫,並將它們路由至微服務。

  • 不清楚的域名:系統的過早分解可能會很昂貴,尤其是當域不清楚時,並且可能會錯誤地解決服務邊界。領域驅動設計(DDD)是理解領域的機制,事件風暴是確定領域邊界的一種技術。

  • 識別微服務:您可以使用 DDD 作為識別微服務的關鍵工具。若要識別微服務,請尋找服務類別之間的自然分割。許多服務將擁有自己的數據訪問對象,並且很容易分離。具有相關業務邏輯的服務以及沒有或很少依賴關係的類別是微服務的好選擇。您可以在分解整體之前重構代碼,以防止緊密耦合。您也應該考慮合規性需求、發行節奏、團隊的地理位置、擴展需求、使用案例驅動的技術需求,以及團隊的認知負荷。

  • 反損毀層:在移轉程序期間,當整體中的功能必須呼叫移轉為微服務的功能時,您應該實作反損毀層 (ACL),將每個呼叫路由至適當的微服務。為了分離並防止對整體內的現有呼叫者進行變更,ACL 可作為轉接器或將呼叫轉換為較新介面的外觀。本指南稍早前面的 ACL 模式的 「實作」 一節會詳細討論這一點。

  • Proxy 層失敗:在移轉期間,Proxy 層會攔截移至整體應用程式的要求,並將其路由至舊版系統或新系統。不過,這個 Proxy 層可能會成為單一故障點或效能瓶頸。

  • 應用複雜性:大型巨石從絞殺無花果圖案中獲益最大。對於完整重構複雜性較低的小型應用程式而言,在微服務架構中重新撰寫應用程式可能會更有效率,而不是移轉它。

  • 服務互動:微服務可以同步或非同步通訊。需要同步通訊時,請考慮逾時是否會造成連線或執行緒集區消耗,進而導致應用程式效能問題。在這種情況下,請使用斷路器模式,針對可能長時間失敗的作業傳回立即失敗。使用事件和訊息佇列可以實現非同步通訊。

  • 資料彙總:在微服務架構中,資料會分散在各個資料庫中。當需要數據匯總時,可以AWS AppSync在前端使用,或者在後端使用命令查詢責任隔離(CQRS)模式。

  • 資料一致性:微服務擁有其資料存放區,而整合式應用程式也可能使用此資料。若要啟用共用,您可以使用佇列和代理程式,同步處理新微服務的資料存放區與整體應用程式的資料庫。但是,這可能會導致兩個資料存放區之間的資料備援和最終一致性,因此我們建議您將其視為戰術解決方案,直到您能夠建立長期解決方案 (例如資料湖) 為止。

實作

在扼殺程序圖模式中,您可以用新的服務或應用程序替換特定功能,一次一個組件。代理層攔截到轉到整體應用程序的請求,並將它們路由到舊系統或新系統。由於 Proxy 層會將使用者路由至正確的應用程式,因此您可以將功能新增至新系統,同時確保整體繼續運作。新系統最終會取代舊系統的所有功能,您可以將其解除委任。

高階架構

在下圖中,整合式應用程式有三種服務:使用者服務、購物車服務和帳戶服務。購物車服務取決於使用者服務,而應用程式會使用整合式關聯式資料庫。

具有三種服務的整合式應用程式

第一個步驟是在店面 UI 和整合式應用程式之間新增代理層。開始時,Proxy 會將所有流量路由到整合式應用程式。

將代理添加到整體應用程序

當您想要將新功能新增至應用程式時,您可以將它們實作為新的微服務,而不是將功能新增至現有的整體式。但是,您將繼續修復整體中的錯誤,以確保應用程序的穩定性。在下圖中,代理層根據 API URL 將調用路由到整體或新的微服務。

代理將呼叫路由到整體式或新的微服務

添加反腐敗層

在下列架構中,使用者服務已移轉至微服務。購物車服務會呼叫使用者服務,但實作不再可用於整體式。此外,新移轉服務的介面可能與整合式應用程式內的先前介面不相符。若要解決這些變更,您需要實作 ACL。在移轉程序期間,當整體式中的功能需要呼叫移轉為微服務的功能時,ACL 會將呼叫轉換為新介面,並將它們路由至適當的微服務。

新增一個 ACL

您可以在整合式應用程式內部實作 ACL,做為已移轉之服務專屬的類別;例如,UserServiceFacade或。UserServiceAdapterACL 必須在所有相依服務移轉至微服務架構之後解除委任。

當您使用 ACL 時,購物車服務仍會呼叫整體內的使用者服務,而且使用者服務會透過 ACL 將呼叫重新導向至微服務。購物車服務仍應呼叫使用者服務,而不知道微服務移轉。這種鬆散的耦合是減少回歸和業務中斷所必需的。

處理數據同步

最佳作法是,微服務應該擁有其資料。用戶服務將其數據存儲在自己的數據存儲中。它可能需要將資料與整合式資料庫同步處理,以處理相依性 (例如報表),以及支援尚未準備好直接存取微服務的下游應用程式。整合式應用程式也可能需要尚未移轉至微服務的其他函式和元件的資料。因此,新的微服務和整體之間的資料同步是必要的。若要同步處理資料,您可以引入使用者微服務與整合式資料庫之間的同步處理代理程式,如下圖所示。每當其數據庫更新時,用戶微服務都會向隊列發送事件。同步處理代理程式會偵聽佇列,並持續更新整合式資料庫。整體式資料庫中的資料對於正在同步處理的資料最終是一致的。

新增同步處理代理程式

遷移其他服務

當購物車服務從整合式應用程式移轉出來時,系統會修訂其程式碼以直接呼叫新服務,因此 ACL 不再路由這些呼叫。下圖說明此架構。

遷移其他服務

下圖顯示了最終的勒死狀態,其中所有服務都已從整體式遷移出來,只剩下整體的骨架。歷史資料可移轉至個別服務所擁有的資料倉庫。ACL 可以被刪除,並且整體已準備好在此階段退役。

最終勒死狀態

下圖顯示整合式應用程式解除委任之後的最終架構。您可以根據應用程式的需求,透過以資源為基礎的 URL (例如http://www.storefront.com/user) 或透過其自己的網域 (例如http://user.storefront.com) 來託管個別微服務。如需使用主機名稱和路徑將 HTTP API 公開給上游消費者的主要方法的詳細資訊,請參閱 API 路由模式一節。

解除委任整體後的最終體系結構

使用AWS服務實施

使用 API Gateway 作為應用程式代理

下圖顯示了整體應用程序的初始狀態。假設它已使用 lift-and-shift 策略遷移到AWS,因此它在 Amazon 彈性運算雲端 (Amazon EC2) 執行個體上執行,並使用 Amazon Relational Database Service (Amazon RDS) 資料庫。為了簡單起見,該架構使用單一虛擬私有雲 (VPC) 與一個私有子網路和一個公有子網路,我們假設微服務最初將部署在相同的。AWS 帳戶(生產環境的最佳作法是使用多帳戶架構來確保部署的獨立性。) EC2 執行個體位於公有子網路中的單一可用區域,且 RDS 執行個體位於私有子網路中的單一可用區域中。亞馬遜 Simple Storage Service (Amazon S3) 存儲靜態資產 JavaScript,例如網站的 CSS 和反應文件。

使用絞殺器圖案時的整體應用程序的初始狀態

在下列架構中,AWS Migration Hub Refactor SpacesAmazon API Gateway 部署在整合式應用程式前面。重構空間會在您的帳戶內建立重構基礎結構,而 API Gateway 則是將呼叫路由至整體式的代理層。最初,所有呼叫都通過代理層路由到整體應用程序。如前所述,代理層可能會成為單一失敗點。不過,使用 API Gateway 做為 Proxy 可降低風險,因為它是無伺服器異地同步備份服務。

使用 API Gateway 實現絞殺程序無花果模式

使用者服務會遷移至 Lambda 函數,而 Amazon DynamoDB 資料庫則會儲存其資料。Lambda 服務端點和預設路由會新增至重構空間,而 API Gateway 會自動設定為將呼叫路由至 Lambda 函數。有關實施詳細信息,請參閱迭代應用程序現代化研討會中的單元 2。

使用 API Gateway 實現絞殺程序圖案:配置路由

在下圖中,購物車服務也已從整體式移轉到 Lambda 函數中。另外一個路由和服務端點會新增至重構空間,流量會自動切換至 Cart Lambda 函數。Lambda 函數的資料存放區由亞馬遜管理 ElastiCache。整合式應用程式仍會與 Amazon RDS 資料庫一起保留在 EC2 執行個體中。

用絞殺無花果圖案將服務移出巨石

在下圖中,最後一個服務(帳戶)從整體移轉到 Lambda 函數中。它繼續使用原始的亞馬遜 RDS 數據庫。新架構現在有三個微服務,其中包含不同的資料庫。每個服務都使用不同類型的資料庫。這種使用專門建置的資料庫來滿足微服務的特定需求的概念稱為「多邊形持續性」。Lambda 函數也可以使用不同的程式設計語言來實作,視使用案例而定。在重構期間,重構空間會自動將流量切換和路由至 Lambda。如此一來,您的建置人員就能節省架構、部署和設定路由基礎結構所需的時間。

用絞殺無花果圖案將所有服務移出巨石

使用多個帳戶

在先前的實作中,我們針對單一應用程式使用具有私有子網路和公有子網路的單一 VPC,為了簡單起見,我們在同AWS 帳戶一個虛擬伺服器中部署了微服務。不過,在真實世界的案例中,這種情況很少會出現,因AWS 帳戶為部署獨立性而經常部署多個微服務。在多帳戶結構中,您需要配置從整體傳輸流量到不同帳戶中的新服務。

重構空間可協助您建立和設定AWS基礎結構,以便將 API 呼叫路由到遠離整合式應用程式。重構空間會協調您AWS帳戶內的 API GatewayNetwork Load Balancer 和資源型 AWS Identity and Access Management(IAM) 政策,做為其應用程式資源的一部分。您可以透明地將單一AWS 帳戶或多個帳戶中的新服務新增至外部 HTTP 端點。所有這些資源都在您的內部進行協調,並AWS 帳戶且可以在部署後進行自訂和設定。

假設使用者和購物車服務部署到兩個不同的帳戶,如下圖所示。當您使用重構空間時,您只需要設定服務端點和路由。重構空間可自動執行 API Gateway — Lambda 整合和 Lambda 資源政策的建立,因此您可以專注於安全地重構整體服務。

實現絞殺無花果模式 AWS Migration Hub Refactor Spaces

如需有關使用重構空間的影片教學課程,請參閱使用增量重構應用程式。AWS Migration Hub Refactor Spaces

工作坊

博客參考

相關內容