Azure 上任務關鍵性工作負載的應用程式設計
當您設計應用程式時,功能和非功能性應用程式需求都很重要。 此設計區域描述架構模式和擴展策略,以幫助您的應用程式在面對失敗時保持韌性。
重要
本文是 Azure 架構完善框架中任務關鍵型工作負載 系列的一部分。 如果您不熟悉這個系列,我們建議您從《什麼是任務關鍵性工作負載?》開始。
縮放單位架構
理想情況下,解決方案的所有功能層面必須能夠自動擴展以回應負載,並調整以適應需求的變化。 建議您使用縮放單位架構,透過區間化將端對端延展性優化,並標準化新增和移除容量的程式。 縮放單位是可獨立調整的邏輯單位或函式。 單位可以由程式碼元件、應用程式託管平台、涵蓋相關元件的部署戳記,甚至包括支援多租使用者需求的訂用帳戶所組成。
我們建議使用此方法,因為它可解決個別資源和整個應用程式的縮放限制。 它有助於處理複雜的部署和更新場景,因為規模單位可以作為一個單位進行部署。 此外,您可以在將使用者流量導向至單元之前,先測試及驗證單元中的特定元件版本。
假設您的任務關鍵性應用程式是在線產品目錄。 其具有處理產品批注和評等的使用者流程。 流程會使用 API 來擷取和張貼批注和評等,以及支援 OAuth 端點、數據存放區和消息佇列等元件。 無狀態 API 端點代表需要能夠隨時調整變更的細分功能單元。 基礎應用程式平臺也必須能夠據以調整。 為了避免效能瓶頸,下游元件和相依性也必須相應調整為適當的程度。 它們可以獨立擴展,作為各自的擴展單元,也可以一起擴展,作為單一邏輯單元的一部分。
範例比例單位
下圖顯示縮放單位的可能範圍。 範圍的範圍從微服務 Pod 到叢集節點和區域部署戳記不等。
設計考量
[範圍]。 縮放單位的範圍、縮放單位與其元件之間的關聯性,應根據容量模型來定義。 考慮效能的非功能性要求。
縮放限制。 Azure 訂用帳戶的規模限制和配額可能會影響應用程式設計、技術選擇以及縮放單位的定義。 縮放單位可協助您略過服務的縮放限制。 例如,如果一個單位中的 AKS 叢集只能有 1,000 個節點,您可以使用兩個單位將該限制增加到 2,000 個節點。
預期的負載。 使用每個使用者流程的要求數目、預期的尖峰要求率(每秒要求數),以及每日/每周/季節性流量模式,以通知核心規模需求。 也考慮流量和數據量的預期成長模式。
效能降低的接受範圍。 判斷高回應時間的降級服務在負載下是否可接受。 當您將所需的容量模型化時,負載下解決方案的必要效能是關鍵因素。
非功能性需求。 技術和商務案例對於復原、可用性、延遲、容量和可觀察性有明顯的考慮。 在關鍵端對端使用者流程中分析這些需求。 您在使用者流程層級的設計、決策和技術選擇中會有相對的彈性。
設計建議
定義規模單位的適用範圍,以及將觸發單位調整的限制條件。
確定所有應用程式元件都可以獨立調整,或作為包含其他相關元件的縮放單位的一部分。
根據容量模型和非功能需求,定義縮放單位之間的關聯性。
定義區域部署戳記,以將區域應用程式資源的布建、管理和作業統一到異質但相互依賴的縮放單位。 隨著負載增加,可以在相同的 Azure 區域內或不同的區域內部署額外的戳記,以水平調整解決方案。
使用 Azure 訂用帳戶作為縮放單位,讓單一訂用帳戶內的縮放限制不會限制延展性。 此方法適用於具有大量流量的高規模應用程式案例。
在識別的流量模式周圍建立所需的容量模型,以確保在尖峰時間布建足夠的容量,以防止服務降低。 或者,在離峰時段優化容量。
測量執行擴展和縮減操作所需的時間,以確保流量的自然變化不會造成不可接受的服務品質下降。 以作業計量追蹤調整作業持續時間。
注意
當您在 Azure 著陸區中進行部署時,請確保著陸區的訂用帳戶專門用於該應用程式,以提供明確的管理界限,並避免 Noisy Neighbor 反模式。
全球分布
不可能避免任何高度分散式環境中的失敗。 本節提供減輕許多錯誤案例的策略。 應用程式必須能夠承受地區性和區域性故障。 它必須部署在作用中/主動模型中,以便將負載分散到所有區域。
觀看這段影片,了解如何在任務關鍵性應用程式中規劃失敗並將韌性最大化:
設計考量
備援。 您的應用程式必須部署到多個區域。 此外,在區域內,我們強烈建議您使用 可用性區域 以實現數據中心級別的故障容忍。 可用性區域之間的延遲小於 2 毫秒。 對於在不同區域之間頻繁通信的工作負載,此延遲可能會對區域間的數據傳輸造成效能損失。
主動/主動模型。 建議使用主動/主動部署策略,因為它可最大化可用性,並提供較高的複合服務等級協定 (SLA)。 不過,對於許多應用程式案例,它可能會帶來數據同步處理和一致性方面的挑戰。 在考慮增加成本和工程工作量的取捨的同時,解決數據平臺層級的挑戰。
跨多個雲端提供者的主動/主動部署,是一種潛在的方式來減少對單一雲端提供者內全域資源的依賴。 不過,多雲端主動/主動部署策略為 CI/CD 帶來了相當大的複雜性。 此外,鑒於雲端提供者之間的資源規格和功能差異,您需要每個雲端的特製化部署戳記。
地理分佈。 工作負載可能有地理數據存儲地、數據保護和數據保留的合規性需求。 請考慮數據必須位於的特定區域,或需要部署資源的位置。
要求來源。 使用者或相依系統的地理鄰近性和密度應該指導關於全球分佈的設計決策。
連接性。 使用者或外部系統存取工作負載的方式會影響您的設計。 請考慮應用程式是否可透過使用 VPN 或 Azure ExpressRoute 線路的公用因特網或專用網使用。
如需平台層級的設計建議和配置選擇,請參閱 應用程式平台:全球分布。
鬆散結合的事件驅動架構
耦合 透過定義完善的介面實現服務間的通訊。 鬆散耦合可讓應用程式元件獨立運作。 一種微服務架構風格符合任務關鍵性需求。 它可藉由防止串聯失敗來促進高可用性。
針對鬆散結合,我們強烈建議您納入事件驅動設計。 透過中繼的異步訊息處理可以建置復原能力。
在某些情況下,應用程式可以結合鬆散且緊密結合,視商務目標而定。
設計考量
運行時間相依性。 鬆散結合的服務不應受限於使用相同的計算平臺、程序設計語言、運行時間或操作系統。
調整大小。 服務應該能夠獨立擴展。 優化基礎結構和平台資源的使用。
容錯。 失敗應該分開處理,而且不應該影響用戶端交易。
交易完整性。 請考慮資料的生成與持續性在個別服務中發生的影響。
分散式追蹤. 端對端追蹤可能需要複雜的協調流程。
設計建議
將微服務界限與重要的使用者流程對齊。
盡可能使用事件驅動的異步通訊,以支援可持續的規模和最佳效能。
使用 Outbox 和交易式會話等模式來保證一致性,確保每個訊息都被正確地處理。
範例:事件驅動方法
任務關鍵在線參考實現會使用微服務來處理單一業務交易。 它會使用訊息中介器和工作執行緒,以異步方式套用寫入作業。 讀取作業是同步的,結果會直接傳回給呼叫端。
顯示事件驅動通訊的圖表。
應用程式程式代碼中的復原模式和錯誤處理
任務關鍵性應用程式必須設計為具復原性,以便儘可能解決許多失敗案例。 此復原功能可最大化服務可用性和可靠性。 應用程式應該具有自我修復功能,您可以使用指退與後退和斷路器等設計模式來實作。
對於您無法在應用程式邏輯中完全減輕的非暫時性失敗,健康模型和操作包覆器必須執行糾正措施。 應用程式程式代碼必須納入適當的檢測和記錄,以通知健康情況模型,並在必要時協助進行後續的疑難解答或根本原因分析。 您必須實作分散式追蹤,以提供呼叫端在發生失敗時包含關聯 ID 的完整錯誤訊息。
像 Application Insights 這樣的工具可以幫助您查詢、關聯和視覺化應用程式的追蹤。
設計考量
適當的設定。 短暫問題導致連鎖故障並不罕見。 例如,重試而不適當的退避會在服務進行節流時加劇問題。 您可以以線性方式空間重試延遲,或以指數方式增加延遲,以透過增加的延遲來回復。
健康指標。 您可以在應用程式程式碼中公開功能檢查,方法是使用健康端點,讓外部解決方案進行輪詢以取得應用程式元件的健康狀態。
設計建議
以下是一些用於提升應用程式彈性的 常見軟體工程模式:
模式 | 摘要 |
---|---|
佇列型負載平衡 | 引入消費者和所需資源之間的緩衝區,以確保負載水平穩定。 當消費者請求排入佇列時,工作進程會依照工作設置的步調,並根據被請求資源的處理能力,來處理請求。 如果消費者期望其要求獲得回覆,您需要實施一個獨立的回應機制。 套用優先順序,以便先執行最重要的活動。 |
斷路器 | 藉由等候復原或快速拒絕要求,而不是在等候無法使用的遠端服務或資源時封鎖,以提供穩定性。 此模式也適用於處理可能在連線到遠端服務或資源時發生的錯誤,這些錯誤可能需要不定的時間段才能復原。 |
艙壁 | 嘗試根據負載和可用性需求,將服務實例分割成群組,隔離失敗以維持服務功能。 |
Saga 設計模式 | 透過確保服務透過定義的事件或訊息通道彼此更新,來管理具有獨立資料存放區之微服務的數據一致性。 每個服務都會執行本地交易來更新其自身狀態,並發布事件以觸發該協作流程中的下一個本地交易。 如果服務更新失敗,Saga 會執行補償交易來抵銷先前的更新步驟。 個別服務更新步驟本身可以實作復原模式,例如重試。 |
健康端點監控 | 在應用程式中實作功能檢查,外部工具可以定期透過公開的端點存取。 您可以使用關鍵作業計量來解譯端點的回應,以通知應用程式健康情況並觸發作業回應,例如引發警示或執行補償復原部署。 |
重試 | 以簡潔且透明的方式處理暫時性失敗。 - 如果錯誤不太可能是暫時性的而且再次嘗試作業不太可能成功,則取消操作。 - 如果錯誤異常或罕見,且如果立即嘗試,作業可能會成功,請重試。 - 如果錯誤是由可能需要短時間進行復原的條件所造成,像是網路連線問題或高負載問題,請稍後重試。 套用適當的退退策略,因為重試延遲增加。 |
節流 | 控制應用程式元件所使用的資源耗用量,防止它們變得過度過度使用。 當資源達到負載閾值時,它會延遲優先順序較低的作業,並降低非必要功能,讓基本功能可以繼續,直到有足夠的資源可供返回正常作業為止。 |
以下是一些其他建議:
使用廠商提供的 SDK,例如 Azure SDK,以連線到相依服務。 使用內建的復原功能,而不是實作自定義功能。
在重試失敗的相依性呼叫時套用適當的退避策略,以避免發生自我造成的 DDoS 案例。
定義所有應用程式微服務小組的一般工程準則,以在應用層級復原模式的使用中推動一致性和速度。
請考慮使用經過實證的標準化套件來實作復原模式,例如 C# Polly 或適用於 Java 的 sentinel 。 此外,NServiceBus 或 MassTransit 等傳訊架構提供內建的復原功能,這有助於避免需要額外的可靠性程序代碼。
針對所有追蹤事件和記錄訊息使用相互關聯標識碼,將它們連結至指定的要求。 針對所有呼叫,不只是失敗的要求,將相關聯的識別碼回傳給呼叫者。
針對所有記錄訊息使用結構化記錄。 針對應用程式追蹤、計量和記錄選取統一的作業數據接收,讓操作員能夠輕鬆地偵錯問題。 如需詳細資訊,請參閱 收集、匯總及儲存雲端應用程式的監視數據。
請確保作業數據與業務需求結合使用,以作為應用程式健康情況模型的參考。
程序設計語言選取
請務必選取正確的程序設計語言和架構。 這些決策通常是由組織中的技能集或標準化技術所驅動。 不過,評估各種語言和架構的效能、復原能力和整體功能至關重要。
設計考量
開發工具包功能。 Azure 服務 SDK 以各種語言提供的功能有差異。 這些差異可能會影響您選擇的 Azure 服務或程式設計語言。 例如,如果 Azure Cosmos DB 是可行的選項,Go 可能不是適當的開發語言,因為沒有第一方 SDK。
功能更新。 請考慮 SDK 為所選語言添加新功能的更新頻率。 常用的 SDK,例如 .NET 和 Java 連結庫,會經常更新。 其他語言的 SDK 或其他類型的 SDK 可能會較不頻繁更新。
多個程式設計語言或架構。 您可以使用多種技術來支援各種複合工作負載。 不過,您應該避免蔓延,因為它引進了管理複雜度和操作挑戰。
計算選項。 舊版或專屬軟體可能無法在 PaaS 服務中執行。 此外,您可能無法在容器中包含舊版或專屬軟體。
設計建議
評估所有相關的 Azure SDK,瞭解您需要的功能,以及您選擇的程式設計語言。 驗證其與非功能需求的一致性。
優化微服務層級的程式設計語言和架構選擇。 適當地使用多個技術。
設定 .NET SDK 的優先順序,以將可靠性和效能優化。 .NET Azure SDK 通常會提供更多功能,而且會經常更新。
後續步驟
查看應用程式平台的相關事項。