Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Das Bulkhead-Muster ist eine Art von Anwendungsentwurf, der fehlertolerant ist. In einer Bulkhead-Architektur, auch als zellenbasierte Architektur bezeichnet, werden Elemente einer Anwendung in Pools isoliert, sodass die anderen Elemente weiterhin funktionieren, wenn ein Fehler auftritt. Das Bulkhead-Muster wird nach den abschnittierten Partitionen (Bulkheads) eines Schiffsrumpfes benannt. Wenn eine Schottwand eines Schiffs beschädigt ist, füllt sich nur der beschädigte Abschnitt mit Wasser, sodass das Schiff nicht sinkt.
Kontext und Problem
Eine cloudbasierte Anwendung kann mehrere Dienste enthalten, und jeder Dienst verfügt über einen oder mehrere Verbraucher. Übermäßige Auslastung oder Fehler in einem Dienst wirken sich auf alle Verbraucher des Diensts aus.
Außerdem kann ein Verbraucher Anforderungen an mehrere Dienste gleichzeitig senden und Ressourcen für jede Anforderung verwenden. Wenn der Verbraucher eine Anforderung an einen falsch konfigurierten oder nicht reagierenden Dienst sendet, bleiben die Ressourcen, die die Anforderung des Clients verwendet, möglicherweise für einen längeren Zeitraum nicht verfügbar. Wenn anforderungen an den Dienst fortgesetzt werden, sind diese Ressourcen möglicherweise erschöpft. Der Verbindungspool des Clients kann z. B. erschöpft sein. Zu diesem Zeitpunkt sind die Anfragen des Verbrauchers an andere Dienste betroffen. Schließlich kann der Verbraucher keine Anfragen an andere Dienste senden, nicht nur den ursprünglichen nicht reagierenden Dienst.
Die Ressourcenausschöpfung wirkt sich auf Dienste aus, die mehrere Verbraucher haben. Viele Anforderungen von einem Client können die verfügbaren Ressourcen im Dienst ausschöpfen. Die Ressourcenerschöpfung kann bedeuten, dass andere Verbraucher den Dienst nicht nutzen können, was zu einem kaskadierenden Fehlereffekt führt.
Lösung
Partitionieren Von Dienstinstanzen in verschiedene Gruppen basierend auf den Anforderungen der Verbraucherlast und -verfügbarkeit. Dieses Design hilft beim Isolieren von Fehlern. Sie können die Dienstfunktionalität für einige Verbraucher auch während eines Ausfalls erhalten.
Ein Verbraucher kann auch Ressourcen partitionieren, um sicherzustellen, dass ressourcen, die zum Aufrufen eines Diensts verwendet werden, keine Auswirkungen auf die Ressourcen haben, die zum Aufrufen eines anderen Diensts verwendet werden. Beispielsweise wird einem Verbraucher, der mehrere Dienste aufruft, für jeden Dienst möglicherweise ein Verbindungspool zugewiesen. Wenn ein Dienst fehlschlägt, wirkt es sich nur auf den Verbindungspool aus, der diesem Dienst zugewiesen ist. Der Verbraucher kann weiterhin andere Dienste nutzen.
Dieses Muster bietet folgende Vorteile:
Verbraucher und Dienste werden vor kaskadierenden Fehlern isoliert. Ein Problem, das einen Verbraucher oder Dienst betrifft, kann innerhalb eines eigenen Abgrenzungsbereichs isoliert werden, um zu verhindern, dass die gesamte Lösung möglicherweise fehlschlägt.
Behält einige Funktionen bei, wenn ein Dienstfehler auftritt. Andere Dienste und Features der Anwendung funktionieren weiterhin.
Bietet unterschiedliche Qualität der Servicelevels für den Einsatz von Anwendungen. Sie können einen Verbraucherpool mit hoher Priorität für die Verwendung von Diensten mit hoher Priorität konfigurieren.
Im folgenden Diagramm sind Bulkheads um Verbindungspools strukturiert, die einzelne Dienste aufrufen. Wenn Dienst A fehlschlägt oder ein Problem verursacht, ist der Verbindungspool isoliert, sodass nur Arbeitslasten betroffen sind, die dem Dienst A zugewiesenen Threadpool verwenden. Arbeitsauslastungen, die Service B und C verwenden, sind nicht betroffen und können ohne Unterbrechung weiterarbeiten.
Diagramm, das zeigt, wie Trennwände um Verbindungspools strukturiert sind, die einzelne Dienste aufrufen.
Diagramm mit zwei Workloads, Workload 1 und Workload 2 und drei Diensten, Service A, Service B und Service C. Workload 1 verwendet einen Verbindungspool, der Dienst A zugewiesen ist. Workload 2 verwendet zwei Verbindungspools. Einem Verbindungspool wird Service B zugewiesen, und der andere wird Service C zugewiesen. Der Verbindungspool, den Workload 1 verwendet, ist isoliert. Die verbindungspools, die Workload 2 verwendet, können weiterhin Service B und Service C aufrufen.
Das folgende Diagramm zeigt mehrere Clients, die einen einzelnen Dienst aufrufen. Jedem Client wird eine separate Dienstinstanz zugewiesen. Client 1 führt zu viele Anforderungen aus und überfordert seine Instanz. Da jede Dienstinstanz von den anderen isoliert ist, können die anderen Clients weiterhin Anrufe tätigen.
Diagramm mit drei Clients, Client 1, Client 2 und Client 3 sowie drei Dienstinstanzen, die jeweils Teil von Service A sind. Jeder Client stellt eine Verbindung mit einer eigenen Dienstinstanz bereit. Die Dienstinstanzen sind isoliert. Wenn Client 1 seine Instanz überfordert, sind Clients 2 und 3 nicht betroffen.
Probleme und Überlegungen
Berücksichtigen Sie die folgenden Punkte, wenn Sie sich für die Implementierung dieses Musters entscheiden:
Definieren Sie Partitionen entsprechend den geschäftlichen und technischen Anforderungen der Anwendung.
Wenn Sie taktisches domänengesteuertes Design zum Entwerfen von Mikroservices verwenden, sollten Partitionsgrenzen an den gebundenen Kontexten ausgerichtet sein.
Wenn Sie Dienste oder Verbraucher in Bulkheads partitionieren, berücksichtigen Sie die Isolationsebene der Technologie und den Aufwand in Bezug auf Kosten, Leistung und Verwaltbarkeit.
Um eine komplexere Fehlerbehandlung zu bieten, sollten Sie Bulkhead mit Retry, Circuit Breaker und Throttling Patterns kombinieren.
Wenn Sie Consumer in Bulkheads partitionieren, sollten Sie Prozesse, Threadpools und Semaphore verwenden. Projekte wie resilience4j und Polly bieten ein Framework zur Erstellung von Schutzmechanismen für Verbraucher an.
Wenn Sie Dienste in Bulkheads partitionieren, sollten Sie sie in separaten virtuellen Computern, Containern oder Prozessen bereitstellen. Container bieten eine gut ausgewogene Ressourcenisolation mit relativ geringem Mehraufwand.
Dienste, die mithilfe asynchroner Nachrichten kommunizieren, können über verschiedene Warteschlangengruppen isoliert werden. Jede Warteschlange kann über einen dedizierten Satz von Instanzen verfügen, die Nachrichten in der Warteschlange verarbeiten, oder eine einzelne Gruppe von Instanzen, die einen Algorithmus verwenden, um die Verarbeitung zu entqueue und zu verteilen.
Bestimmen Sie den Grad der Granularität für die Bulkheads. Wenn Sie z. B. Mandanten über Partitionen verteilen möchten, können Sie jeden Mandanten in einer separaten Partition platzieren oder mehrere Mandanten in einer Partition platzieren.
Überwachen Sie die Leistungsfähigkeit und die Service-Level-Vereinbarung (SLA) der einzelnen Partitionen.
Verwenden Sie integrierte Plattformsteuerelemente wie Azure API Management Rate Limits, Azure Cosmos DB Request Unit (RU) Isolation und Ressourcengrenzwerte in Azure Kubernetes Service (AKS) oder Azure Container Apps. Erstellen Sie diese Drosselungs- und Isolationsmechanismen nicht in Ihrem Anwendungscode neu.
KI- und Inferenzarbeitslasten erfordern häufig strenge Sicherheitsbarrieren aufgrund von Kontingenten auf der Bereitstellungsebene und Begrenzungen der Parallelität, z. B. wenn Azure OpenAI-Bereitstellungen pro Arbeitslast oder pro Mandant isoliert werden.
Wann Sie dieses Muster verwenden sollten
Verwenden Sie dieses Muster in folgenden Fällen:
- Sie möchten Ressourcen für bestimmte Abhängigkeiten isolieren, sodass sich eine Unterbrechung in einem Dienst nicht auf die gesamte Anwendung auswirkt.
- Sie möchten kritische Verbraucher von Standardkonsumenten isolieren.
- Sie müssen die Anwendung vor kaskadierenden Fehlern schützen.
Dieses Muster ist möglicherweise nicht geeignet, wenn:
- Eine weniger effiziente Nutzung von Ressourcen ist im Projekt möglicherweise nicht akzeptabel.
- Die zusätzliche Komplexität ist nicht erforderlich.
Workloadentwurf
Bewerten Sie, wie Sie das Bulkhead-Muster im Design einer Workload einsetzen, um die in den Azure Well-Architected Framework-Säulen behandelten Ziele und Prinzipien zu erfüllen. Die folgende Tabelle enthält Anleitungen dazu, wie dieses Muster die Ziele jeder Säule unterstützt.
| Säule | So unterstützt dieses Muster die Säulenziele |
|---|---|
| Zuverlässigkeitsentwurfsentscheidungen helfen Ihrer Arbeitsauslastung, ausfallsicher zu werden und sicherzustellen, dass sie nach auftreten eines Fehlers wieder in einen voll funktionsfähigen Zustand versetzt wird. | Die Fehlerisolationsstrategie wurde durch die beabsichtigte und vollständige Segmentierung zwischen Komponenten eingeführt, um Fehler auf das Schott zu beschränken, das das Problem erfährt, wodurch Auswirkungen auf andere Schotts verhindert werden. - RE:02 Kritische Abläufe - RE:07 Selbsterhaltung |
| Sicherheitsdesignentscheidungen tragen dazu bei, die Vertraulichkeit, Integrität und Verfügbarkeit der Daten und Systeme Ihrer Workload sicherzustellen. | Die Segmentierung zwischen Komponenten trägt dazu bei, Sicherheitsvorfälle auf den gefährdete Bulkhead zu beschränken. - SE:04 Segmentierung |
| Performance Efficiency hilft Ihrem Workload durch Optimierungen bei Skalierung, Daten und Code, die Anforderungen effizient zu erfüllen . | Jeder Bulkhead kann individuell skalierbar sein, um die Anforderungen der im Bulkhead gekapselten Aufgabe effizient zu erfüllen. - PE:02 Kapazitätsplanung - PE:05 Skalierung und Partitionierung |
Wenn dieses Muster Kompromisse innerhalb einer Säule einführt, sollten Sie sie gegen die Ziele der anderen Säulen berücksichtigen.
Beispiel
Die folgende Kubernetes-Konfigurationsdatei erstellt einen isolierten Container zum Ausführen eines einzelnen Diensts, mit eigenen CPU- und Arbeitsspeicherressourcen und eigenen CPU- und Arbeitsspeicherlimits.
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"
Nächste Schritte
- Verwenden Sie Richtlinien für die API-Verwaltungsrateinschränkung , um den Anforderungsdurchsatz pro Client zu steuern.
- Verwenden Sie Parallelitätssteuerelemente von Azure Functions , um parallele Ausführungen einzuschränken.
- Legen Sie Ressourcenbeschränkungen für Container-Apps fest, um CPU und Arbeitsspeicher pro Workload zu steuern.
- Weisen Sie den Azure Cosmos DB RU-Durchsatz pro Container für vorhersehbare Isolation zu.