Mönstret Bulkhead

Mönstret Bulkhead är en typ av programdesign som är tolerant för fel. I en arkitektur med bulkhead isoleras element i ett program i pooler så att de andra fortsätter att fungera om ett fel skulle misslyckas. Det är uppkallat efter de delade partitionerna (bulkheads) för ett skepps skepp. Om fartygets skrov springer läck fylls bara det skott som har en läcka med vatten, så att skeppet inte sjunker.

Kontext och problem

Ett molnbaserat program kan innehålla flera tjänster, där varje tjänst har en eller flera användare. Hög belastning eller fel i en tjänst påverkar alla användare av tjänsten.

Dessutom kan en användare skicka begäranden till flera tjänster samtidigt, vilket tar upp resurser för varje begäran. När användaren skickar en begäran till en tjänst som är felkonfigurerad eller inte svarar, kanske de resurser som används av klientens begäran inte frigörs inom rimlig tid. När begäranden till tjänsten fortsätter att komma kan resurserna bli förbrukade. Till exempel kanske klientens anslutningspool förbrukats. Då påverkas begäranden från konsumenten till andra tjänster. Användaren kan till slut inte längre skicka begäranden till andra tjänster, inte bara den ursprungliga tjänsten som inte svarar.

Samma resursproblem påverkar tjänster med flera användare. Ett stort antal begäranden från en klient kan göra slut på tillgängliga resurser i tjänsten. Andra användare kan inte längre använda tjänsten, vilket orsakar ett kaskadfel.

Lösning

Partitionera tjänstinstanser i olika grupper, baserat på användarbelastning och tillgänglighetskrav. Den här designen hjälper dig att isolera fel, och du kan upprätthålla tjänstens funktioner för vissa användare även om ett fel inträffar.

En användare kan också partitionera resurser för att säkerställa att resurser som används för att anropa en tjänst inte påverkar de resurser som används för att anropa en annan tjänst. Till exempel kan en användare som anropar flera tjänster tilldelas en anslutningspool för varje tjänst. Om fel uppstår i en tjänst, påverkar detta endast den anslutningspool som tilldelats tjänsten, så att användaren kan fortsätta använda andra tjänster.

Några fördelar med det här mönstret är följande:

  • Isolerar användare och tjänster från kaskadfel. Ett problem som påverkar en användare eller tjänst kan isoleras inom sitt eget vattentäta skott, så att inte hela lösningen påverkas.
  • På så sätt kan du bevara vissa funktioner vid fel i en tjänst. Andra tjänster och funktioner i programmet fortsätter att fungera.
  • Tillåter dig att distribuera tjänster som erbjuder olika tjänstkvalitet för programförbrukning. En användarpool med hög prioritet kan konfigureras för att använda tjänster med hög prioritet.

Följande diagram visar vattentäta skott som strukturerats runt anslutningspooler som anropar enskilda tjänster. Om tjänst A misslyckas eller orsakar andra problem är anslutningspoolen isolerad, så att endast arbetsbelastningar som använder den trådpool som tilldelats tjänst A påverkas. Arbetsbelastningar som använder tjänsterna B och C påverkas inte och kan fortsätta arbeta utan avbrott.

Första diagrammet över mönstret Bulkhead

I nästa diagram visas flera klienter som anropar en enskild tjänst. Varje klient tilldelas en separat tjänstinstans. Klient 1 har gjort för många begäranden och dess instans har överbelastats. Eftersom varje tjänstinstans är isolerad från de andra, kan de andra klienterna fortsätta med sina anrop.

Diagram som visar flera klienter som anropar en enda tjänst.

Problem och överväganden

  • Definiera partitioner runt affärsmässiga och tekniska krav för programmet.
  • När tjänster eller användare partitioneras i vattentäta skott ska du fundera över vilken nivå av isolering som erbjuds av tekniken samt kostnaden vad gäller ekonomi, prestanda och hanterbarhet.
  • Överväg att kombinera de vattentäta skotten med nya försök, kretsbrytare och nätverksbegränsning för att få en mer avancerad hantering av fel.
  • Överväg att använda processer, trådpooler och semaforer när användare partitioneras i vattentäta skott. Projekt som resilience4j ochPolly erbjuder ett ramverk för att skapa bulkheads för konsumenter.
  • Överväg att distribuera tjänster till olika virtuella datorer, containrar eller processer när tjänster partitioneras i vattentäta skott. Containrar erbjuder en bra balans mellan resursisolering och relativt låg kostnad.
  • Tjänster som kommunicerar med hjälp av asynkrona meddelanden kan isoleras via olika uppsättningar av köer. Varje kö kan ha en särskild uppsättning instanser som behandlar meddelanden i kön, eller en enskild grupp av instanser som använder en algoritm för borttagning ur kö och sändningsbearbetning.
  • Fastställ granularitetsnivån för de vattentäta skotten. Om du till exempel vill distribuera klienter mellan partitioner kan du placera varje klient i en separat partition eller placera flera klienter i en partition.
  • Övervaka prestanda och serviceavtal för varje partition.

När du ska använda det här mönstret

Använd det här mönstret om du vill:

  • Isolera resurser som används för att använda en uppsättning serverdelstjänster, särskilt om programmet kan hålla en viss funktionsnivå även om en av tjänsterna inte svarar.
  • Isolera kritiska användare från standardanvändare.
  • Skydda programmet från kaskadfel.

Det här mönstret kanske inte lämpar sig om:

  • Mindre effektiv användning av resurser inte kan godtas i projektet.
  • Ökad komplexitet inte behövs

Exempel

Följande Kubernetes-konfigurationsfil skapar en isolerad container för att köra en enda tjänst med sin egen processor, egna minnesresurser och egna gränser.

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"