Bulkhead 模式是一種應用程式設計,可容忍失敗。 在稱為數據格架構的大容量化架構中,應用程式的專案會隔離到集區中,讓其中一個元素失敗時,其他專案會繼續運作。 它以船體部分分割(艙頭)命名。 如果船隻的船體遭到入侵,只有受損的區段填滿了水,這可防止該船沉沒。
內容和問題
雲端式應用程式可能包含多個服務,每個服務都有一或多個取用者。 服務中過多的負載或失敗會影響服務的所有取用者。
此外,取用者可以使用每個要求的資源,同時將要求傳送至多個服務。 當取用者將要求傳送至設定錯誤或未回應的服務時,用戶端要求所使用的資源可能無法及時釋放。 當服務的要求繼續時,這些資源可能會耗盡。 例如,客戶端的連接集區可能已用盡。 此時,取用者對其他服務的要求會受到影響。 最終取用者無法再將要求傳送至其他服務,而不只是原始沒有回應的服務。
資源耗盡的相同問題會影響多個取用者的服務。 源自一個用戶端的大量要求可能會耗盡服務中的可用資源。 其他取用者無法再取用服務,導致串聯失敗效果。
解決方案
根據取用者負載和可用性需求,將服務實例分割成不同的群組。 此設計有助於隔離失敗,並可讓您維持某些取用者的服務功能,即使在失敗期間也是如此。
取用者也可以分割資源,以確保用來呼叫某個服務的資源不會影響用來呼叫另一個服務的資源。 例如,呼叫多個服務的取用者可能會為每個服務指派連接集區。 如果服務開始失敗,它只會影響為該服務指派的連接集區,讓取用者繼續使用其他服務。
此模式的優點包括:
- 隔離取用者和服務與串聯失敗。 影響取用者或服務的問題可以在其本身的艙口內隔離,以防止整個解決方案失敗。
- 可讓您在服務失敗時保留某些功能。 應用程式的其他服務和功能將繼續運作。
- 可讓您部署服務,以提供不同服務品質來取用應用程式。 高優先順序的取用者集區可以設定為使用高優先順序服務。
下圖顯示圍繞呼叫個別服務之連接集區而建構的大量分頁。 如果服務 A 失敗或造成其他問題,連線集區會隔離,因此只會影響使用指派給服務 A 的線程集區工作負載。 使用服務 B 和 C 的工作負載不會受到影響,而且可以在不中斷的情況下繼續運作。
下圖顯示多個呼叫單一服務的用戶端。 每個客戶端都會指派個別的服務實例。 用戶端 1 已提出太多要求,並壓倒其實例。 因為每個服務實例都與其他實例隔離,因此其他用戶端可以繼續呼叫。
問題和考量
- 定義應用程式商務和技術需求周圍的分割區。
- 如果使用戰術 DDD 來設計微服務,分割區界限應與限定內容一致。
- 將服務或取用者分割成散文時,請考慮技術所提供的隔離等級,以及成本、效能和管理能力方面的額外負荷。
- 請考慮結合分頁與重試、斷路器和節流模式,以提供更複雜的錯誤處理。
- 將取用者分割成大量數據時,請考慮使用進程、線程集區和旗號。 resilience4j 和 Polly 等專案提供建立取用者散文的架構。
- 將服務分割成大量數據時,請考慮將它們部署到不同的虛擬機、容器或進程。 容器在資源隔離方面提供了良好的平衡,額外負荷相當低。
- 使用異步訊息進行通訊的服務可以透過不同的佇列集隔離。 每個佇列可以有一組專用的實例在佇列上處理訊息,或使用演算法來清除佇列和分派處理的單一實例群組。
- 判斷散文艙的粒度層級。 例如,如果您想要將租使用者分散到分割區,您可以將每個租使用者放入不同的分割區,或將數個租使用者放入一個分割區。
- 監視每個分割區的效能和 SLA。
使用此模式的時機
使用此模式來:
- 隔離用來取用一組後端服務的資源,特別是即使其中一個服務沒有回應,應用程式也能提供某種層級的功能。
- 隔離重要取用者與標準取用者。
- 保護應用程式免於串連失敗。
此模式在下列情況下可能不適合:
- 專案中可能無法接受資源效率較低的使用。
- 不需要新增的複雜度
工作負載設計
架構設計人員應評估 Bulkhead 模式在工作負載的設計中如何使用,以解決 Azure 架構良好架構支柱中涵蓋的目標和原則。 例如:
要素 | 此模式如何支援支柱目標 |
---|---|
可靠性設計決策可協助工作負載復原到故障,並確保它會在發生失敗后復原到完全正常運作的狀態。 | 透過元件之間的刻意和完整分割導入的失敗隔離策略,會嘗試只包含問題所在之重頭的錯誤,以防止對其他艙頭造成影響。 - RE:02 重要流程 - RE:07 自我保護 |
安全性 設計決策有助於確保 工作負載數據和系統的機密性、 完整性和 可用性 。 | 元件之間的分割有助於將安全性事件限制在遭入侵的分頁。 - SE:04 分割 |
效能效率可透過調整規模、資料、程式碼達到最佳化,有效率地協助您的工作負載符合需求。 | 每個隔板可以個別調整,以有效率地符合封裝在體塊中的工作需求。 - PE:02 容量規劃 - PE:05 調整和分割 |
如同任何設計決策,請考慮對其他可能以此模式導入之目標的任何取捨。
範例
下列 Kubernetes 組態檔會建立隔離的容器來執行單一服務,並有自己的 CPU 和記憶體資源和限制。
apiVersion: v1
kind: Pod
metadata:
name: drone-management
spec:
containers:
- name: drone-management-container
image: drone-service
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "1"