Share via


Anwendungsentwurf unternehmenskritischer Workloads in Azure

Wenn Sie eine Anwendung entwerfen, sind sowohl funktionale als auch nicht funktionale Anwendungsanforderungen von entscheidender Bedeutung. In diesem Entwurfsbereich werden Architekturmuster und Skalierungsstrategien beschrieben, die dazu beitragen können, ihre Anwendung resilient gegen Fehler zu machen.

Wichtig

Dieser Artikel ist Teil der unternehmenskritischen Workloadreihe von Azure Well-Architected Framework . Wenn Sie mit dieser Reihe nicht vertraut sind, empfehlen wir Ihnen, mit Was ist eine unternehmenskritische Workload zu beginnen?

Architektur der Skalierungseinheiten

Alle funktionalen Aspekte einer Lösung müssen skalierungsfähig sein, um Änderungen der Nachfrage zu erfüllen. Es wird empfohlen, eine Skalierungseinheitsarchitektur zu verwenden, um die End-to-End-Skalierbarkeit durch Kompartimentierung zu optimieren und den Prozess des Hinzufügens und Entfernens von Kapazität zu standardisieren. Eine Skalierungseinheit ist eine logische Einheit oder Funktion, die unabhängig skaliert werden kann. Eine Einheit kann aus Codekomponenten, Anwendungshostingplattformen, bereitstellungsstempeln , die die zugehörigen Komponenten abdecken, und sogar Ausabonnements zur Unterstützung von Anforderungen mit mehreren Mandanten bestehen.

Wir empfehlen diesen Ansatz, da er die Skalierungsgrenzen einzelner Ressourcen und der gesamten Anwendung berücksichtigt. Es hilft bei komplexen Bereitstellungs- und Updateszenarien, da eine Skalierungseinheit als eine Einheit bereitgestellt werden kann. Außerdem können Sie bestimmte Versionen von Komponenten in einer Einheit testen und überprüfen, bevor Sie den Benutzerdatenverkehr an diese weiterleiten.

Angenommen, Ihre unternehmenskritische Anwendung ist ein Online-Produktkatalog. Es verfügt über einen Benutzerflow zum Verarbeiten von Produktkommentaren und -bewertungen. Der Flow verwendet APIs zum Abrufen und Veröffentlichen von Kommentaren und Bewertungen sowie unterstützende Komponenten wie einen OAuth-Endpunkt, einen Datenspeicher und Nachrichtenwarteschlangen. Die zustandslosen API-Endpunkte stellen präzise Funktionseinheiten dar, die sich bei Bedarf an Änderungen anpassen müssen. Die zugrunde liegende Anwendungsplattform muss ebenfalls in der Lage sein, entsprechend zu skalieren. Um Leistungsengpässe zu vermeiden, müssen auch die nachgeschalteten Komponenten und Abhängigkeiten in einem angemessenen Maß skaliert werden. Sie können entweder unabhängig, als separate Skalierungseinheiten oder zusammen als Teil einer einzelnen logischen Einheit skaliert werden.

Beispiel-Skalierungseinheiten

Die folgende Abbildung zeigt die möglichen Bereiche für Skalierungseinheiten. Die Bereiche reichen von Microservicepods über Clusterknoten bis hin zu regionalen Bereitstellungsstempeln.

Diagramm, das mehrere Bereiche für Skalierungseinheiten zeigt.

Überlegungen zum Entwurf

  • Umfang. Der Umfang einer Skalierungseinheit, die Beziehung zwischen Skalierungseinheiten und deren Komponenten sollten gemäß einem Kapazitätsmodell definiert werden. Berücksichtigen Sie nicht funktionale Leistungsanforderungen.

  • Skalierungsgrenzwerte. Skalierungslimits und Kontingente für Azure-Abonnements können sich auf den Anwendungsentwurf, die Technologieauswahl und die Definition von Skalierungseinheiten auswirken. Skalierungseinheiten können Ihnen dabei helfen, die Skalierungsgrenzen eines Diensts zu umgehen. Wenn ein AKS-Cluster in einer Einheit beispielsweise nur über 1.000 Knoten verfügen kann, können Sie zwei Einheiten verwenden, um diesen Grenzwert auf 2.000 Knoten zu erhöhen.

  • Erwartete Auslastung. Verwenden Sie die Anzahl der Anforderungen für jeden Benutzerflow, die erwartete Spitzenanforderungsrate (Anforderungen pro Sekunde) und tägliche/wöchentliche/saisonale Datenverkehrsmuster, um die wichtigsten Skalierungsanforderungen zu informieren. Berücksichtigen Sie auch die erwarteten Wachstumsmuster für Datenverkehr und Datenvolumen.

  • Zulässige Leistungseinbußen. Ermitteln Sie, ob ein heruntergestufter Dienst mit hohen Antwortzeiten unter Last akzeptabel ist. Wenn Sie die erforderliche Kapazität modellieren, ist die erforderliche Leistung der Lösung unter Last ein wichtiger Faktor.

  • Nicht funktionale Anforderungen. Technische und geschäftliche Szenarien haben unterschiedliche Überlegungen zu Resilienz, Verfügbarkeit, Latenz, Kapazität und Beobachtbarkeit. Analysieren Sie diese Anforderungen im Kontext wichtiger End-to-End-Benutzerflows. Sie verfügen über eine relative Flexibilität bei der Entwurfs-, Entscheidungs- und Technologieauswahl auf Benutzerflowebene.

Entwurfsempfehlungen

  • Definieren Sie den Bereich einer Skalierungseinheit und die Grenzwerte, die die Skalierung der Einheit auslösen.

  • Stellen Sie sicher, dass alle Anwendungskomponenten unabhängig oder als Teil einer Skalierungseinheit skaliert werden können, die andere verwandte Komponenten enthält.

  • Definieren Sie die Beziehung zwischen Skalierungseinheiten basierend auf einem Kapazitätsmodell und nicht funktionalen Anforderungen.

  • Definieren Sie einen regionalen Bereitstellungsstempel, um die Bereitstellung, Verwaltung und den Betrieb regionaler Anwendungsressourcen in einer heterogenen, aber voneinander abhängigen Skalierungseinheit zu vereinheitlichen. Wenn die Last zunimmt, können zusätzliche Stempel innerhalb derselben oder unterschiedlicher Azure-Region bereitgestellt werden, um die Lösung horizontal zu skalieren.

  • Verwenden Sie ein Azure-Abonnement als Skalierungseinheit, damit skalierungslimits innerhalb eines einzelnen Abonnements die Skalierbarkeit nicht einschränken. Dieser Ansatz gilt für hochskalige Anwendungsszenarien, die ein erhebliches Datenverkehrsvolumen aufweisen.

  • Modellieren Sie die erforderliche Kapazität für identifizierte Datenverkehrsmuster, um sicherzustellen, dass zu Spitzenzeiten genügend Kapazität bereitgestellt wird, um eine Beeinträchtigung des Diensts zu verhindern. Alternativ können Sie die Kapazität außerhalb der Spitzenzeiten optimieren.

  • Messen Sie die Zeit, die für die Durchführung von Horizontal- und Horizontalskalierungsvorgängen erforderlich ist, um sicherzustellen, dass die natürlichen Schwankungen des Datenverkehrs nicht zu einer inakzeptablen Dienstbeeinträchtigung führen. Verfolgen Sie die Dauer des Skalierungsvorgangs als betriebsbezogene Metrik.

Hinweis

Stellen Sie bei der Bereitstellung in einer Azure-Zielzone sicher, dass das Zielzonenabonnement der Anwendung zugewiesen ist, um eine klare Verwaltungsgrenze bereitzustellen und das Noisy Neighbor-Antimuster zu vermeiden.

Globale Verteilung

Es ist unmöglich, Fehler in einer hoch verteilten Umgebung zu vermeiden. Dieser Abschnitt enthält Strategien zur Entschärfung vieler Fehlerszenarien. Die Anwendung muss in der Lage sein, regionalen und zonalen Ausfällen standzuhalten. Es muss in einem Aktiv/Aktiv-Modell bereitgestellt werden, damit die Last auf alle Regionen verteilt wird.

Sehen Sie sich dieses Video an, um einen Überblick darüber zu erhalten, wie Sie Fehler in unternehmenskritischen Anwendungen planen und die Resilienz maximieren:

Überlegungen zum Entwurf

  • Redundanz. Ihre Anwendung muss in mehreren Regionen bereitgestellt werden. Darüber hinaus wird dringend empfohlen, dass Sie innerhalb einer Region Verfügbarkeitszonen verwenden, um fehlertoleranz auf Rechenzentrumsebene zu ermöglichen. Verfügbarkeitszonen weisen einen Latenzperimeter von weniger als 2 Millisekunden zwischen Verfügbarkeitszonen auf. Bei Workloads, die zonenübergreifend "chatzig" sind, kann diese Latenz zu Leistungseinbußen führen und Bandbreitengebühren für die zonenübergreifende Datenübertragung verursachen.

  • Aktiv/Aktiv-Modell. Eine Aktiv/Aktiv-Bereitstellungsstrategie wird empfohlen, da sie die Verfügbarkeit maximiert und eine höhere sla (Composite Service Level Agreement) bietet. Dies kann jedoch für viele Anwendungsszenarien Herausforderungen in Bezug auf datensynchronisierung und -konsistenz darstellen. Bewältigen Sie die Herausforderungen auf Datenplattformebene, während Sie die Kompromisse in Bezug auf höhere Kosten und technischen Aufwand berücksichtigen.

    Eine Aktiv/Aktiv-Bereitstellung über mehrere Cloudanbieter hinweg ist eine Möglichkeit, die Abhängigkeit von globalen Ressourcen innerhalb eines einzelnen Cloudanbieters zu verringern. Eine Multicloud-Strategie für aktiv/aktiv-Bereitstellungen führt jedoch zu einer erheblichen Komplexität von CI/CD. Angesichts der Unterschiede in den Ressourcenspezifikationen und -funktionen zwischen Cloudanbietern benötigen Sie außerdem spezielle Bereitstellungsstempel für jede Cloud.

  • Geografische Verteilung. Für die Workload gelten möglicherweise Complianceanforderungen für die geografische Datenresidenz, den Datenschutz und die Datenaufbewahrung. Berücksichtigen Sie, ob bestimmte Regionen vorhanden sind, in denen sich Daten befinden müssen oder wo Ressourcen bereitgestellt werden müssen.

  • Anforderungsursprung. Die geografische Nähe und Dichte von Benutzern oder abhängigen Systemen sollte die Entwurfsentscheidungen über die globale Verteilung beeinflussen.

  • Konnektivität. Der Zugriff auf die Workload durch Benutzer oder externe Systeme beeinflusst Ihren Entwurf. Überlegen Sie, ob die Anwendung über das öffentliche Internet oder private Netzwerke verfügbar ist, die VPN- oder Azure ExpressRoute-Leitungen verwenden.

Entwurfsempfehlungen und Konfigurationsoptionen auf Plattformebene finden Sie unter Anwendungsplattform: Globale Verteilung.

Lose gekoppelte ereignisgesteuerte Architektur

Die Kopplung ermöglicht die dienstübergreifende Kommunikation über klar definierte Schnittstellen. Eine lose Kopplung ermöglicht es einer Anwendungskomponente, unabhängig zu arbeiten. Ein Microservices-Architekturstil ist mit unternehmenskritischen Anforderungen konsistent. Es ermöglicht Hochverfügbarkeit, indem kaskadierende Fehler verhindert werden.

Für die lose Kopplung wird dringend empfohlen, ereignisgesteuertes Design zu integrieren. Die asynchrone Nachrichtenverarbeitung über einen Vermittler kann Resilienz schaffen.

Diagramm, das die asynchrone ereignisgesteuerte Kommunikation veranschaulicht.

In einigen Szenarien können Anwendungen eine lose und enge Kopplung kombinieren, je nach Geschäftszielen.

Überlegungen zum Entwurf

  • Laufzeitabhängigkeiten. Lose gekoppelte Dienste sollten nicht auf die Verwendung derselben Computeplattform, Programmiersprache, Runtime oder Betriebssystem beschränkt werden.

  • Skalierung. Dienste sollten unabhängig skaliert werden können. Optimieren Sie die Nutzung von Infrastruktur- und Plattformressourcen.

  • Fehlertoleranz. Fehler sollten separat behandelt werden und sollten sich nicht auf Clienttransaktionen auswirken.

  • Transaktionsintegrität. Betrachten Sie die Auswirkungen der Datenerstellung und -persistenz in separaten Diensten.

  • Verteilte Ablaufverfolgung: Die End-to-End-Ablaufverfolgung erfordert möglicherweise eine komplexe Orchestrierung.

Entwurfsempfehlungen

  • Richten Sie Microservicegrenzen an kritischen Benutzerflows aus.

  • Verwenden Sie nach Möglichkeit ereignisgesteuerte asynchrone Kommunikation, um eine nachhaltige Skalierung und optimale Leistung zu unterstützen.

  • Verwenden Sie Muster wie Posteingang und Transaktionssitzung, um Konsistenz zu gewährleisten, damit jede Nachricht ordnungsgemäß verarbeitet wird.

Beispiel: Ereignisgesteuerter Ansatz

Die Unternehmenskritische Online-Referenzimplementierung verwendet Microservices, um eine einzelne Geschäftstransaktion zu verarbeiten. Schreibvorgänge werden asynchron mit einem Nachrichtenbroker und Worker angewendet. Lesevorgänge sind synchron, wobei das Ergebnis direkt an den Aufrufer zurückgegeben wird.

Diagramm, das die ereignisgesteuerte Kommunikation zeigt.

Resilienzmuster und Fehlerbehandlung im Anwendungscode

Eine unternehmenskritische Anwendung muss so konzipiert sein, dass sie resilient ist, damit sie so viele Fehlerszenarien wie möglich anspricht. Diese Resilienz maximiert die Verfügbarkeit und Zuverlässigkeit der Dienste. Die Anwendung sollte über Selbstheilungsfunktionen verfügen, die Sie mithilfe von Entwurfsmustern wie Wiederholungsversuchen mit Backoff und Circuit Breaker implementieren können.

Bei nicht vorübergehenden Fehlern, die Sie in der Anwendungslogik nicht vollständig entschärfen können, müssen das Integritätsmodell und die betriebsbereiten Wrapper Korrekturmaßnahmen ergreifen. Der Anwendungscode muss eine geeignete Instrumentierung und Protokollierung enthalten, um das Integritätsmodell zu informieren und die nachfolgende Problembehandlung oder Die Analyse der Grundursache nach Bedarf zu erleichtern. Sie müssen die verteilte Ablaufverfolgung implementieren, um dem Aufrufer eine umfassende Fehlermeldung bereitzustellen, die eine Korrelations-ID enthält, wenn ein Fehler auftritt.

Tools wie Application Insights können Ihnen beim Abfragen, Korrelieren und Visualisieren von Anwendungsablaufverfolgungen helfen.

Überlegungen zum Entwurf

  • Richtige Konfigurationen. Es ist nicht ungewöhnlich, dass vorübergehende Probleme kaskadierende Fehler verursachen. Ein Wiederholungsversuch ohne entsprechendes Back-Off verschlimmert beispielsweise das Problem, wenn ein Dienst gedrosselt wird. Sie können raumretry-Verzögerungen linear oder exponentiell erhöhen, um durch wachsende Verzögerungen zurückzuschalten.

  • Integritätsendpunkte. Sie können Funktionsprüfungen im Anwendungscode verfügbar machen, indem Sie Integritätsendpunkte verwenden, die von externen Lösungen abgefragt werden können, um die Integrität von Anwendungskomponenten abzurufen status.

Entwurfsempfehlungen

Hier sind einige gängige Softwareentwicklungsmuster für resiliente Anwendungen:

Muster Zusammenfassung
Warteschlangenbasierter Lastenausgleich Führt einen Puffer zwischen Consumern und angeforderten Ressourcen ein, um konsistente Auslastungsebenen zu gewährleisten. Wenn Consumeranforderungen in die Warteschlange gestellt werden, verarbeitet ein Workerprozess sie mit der angeforderten Ressource in einem Tempo, das vom Worker und der Fähigkeit der angeforderten Ressource zur Verarbeitung der Anforderungen festgelegt wird. Wenn Verbraucher Antworten auf ihre Anforderungen erwarten, müssen Sie einen separaten Antwortmechanismus implementieren. Wenden Sie eine priorisierte Reihenfolge an, damit zuerst die wichtigsten Aktivitäten ausgeführt werden.
Sicherung Bietet Stabilität, indem entweder auf die Wiederherstellung gewartet oder Anforderungen schnell abgelehnt werden, anstatt beim Warten auf einen nicht verfügbaren Remotedienst oder eine nicht verfügbare Ressource zu blockieren. Dieses Muster behandelt auch Fehler, deren Wiederherstellung eine variable Zeit in Anspruch nehmen kann, wenn eine Verbindung mit einem Remotedienst oder einer Remoteressource hergestellt wird.
Bulkhead Versucht, Dienstinstanzen basierend auf Auslastungs- und Verfügbarkeitsanforderungen in Gruppen zu partitionieren und Fehler zu isolieren, um die Dienstfunktionalität aufrechtzuerhalten.
Saga Verwaltet die Datenkonsistenz für Microservices mit unabhängigen Datenspeichern, indem sichergestellt wird, dass Dienste sich gegenseitig über definierte Ereignis- oder Nachrichtenkanäle aktualisieren. Jeder Dienst führt lokale Transaktionen aus, um seinen eigenen Zustand zu aktualisieren, und veröffentlicht ein Ereignis, um die nächste lokale Transaktion in der Saga auszulösen. Wenn ein Dienstupdate fehlschlägt, führt die Saga Ausgleichstransaktionen aus, um vorherigen Dienstupdateschritten entgegenzuwirken. Einzelne Dienstupdateschritte können selbst Resilienzmuster implementieren, z. B. Wiederholungsversuche.
Überwachung des Integritätsendpunkts Implementiert Funktionsprüfungen in einer Anwendung, auf die externe Tools in regelmäßigen Abständen über verfügbar gemachte Endpunkte zugreifen können. Sie können Antworten von den Endpunkten interpretieren, indem Sie wichtige betriebsbezogene Metriken verwenden, um die Anwendungsintegrität zu informieren und operative Antworten auszulösen, z. B. das Auslösen einer Warnung oder das Ausführen einer kompensierenden Rollbackbereitstellung.
Wiederholung Verarbeitet vorübergehende Fehler elegant und transparent.
– Abbrechen, wenn der Fehler unwahrscheinlich ist, dass er vorübergehend ist und wahrscheinlich nicht erfolgreich ist, wenn der Vorgang erneut versucht wird.
- Wiederholen Sie den Vorgang, wenn der Fehler ungewöhnlich oder selten ist und der Vorgang wahrscheinlich erfolgreich ist, wenn es sofort erneut versucht wird.
- Wiederholen Sie nach einer Verzögerung, wenn der Fehler durch eine Bedingung verursacht wird, die möglicherweise eine kurze Zeit für die Wiederherstellung benötigt, z. B. Netzwerkkonnektivität oder Fehler mit hoher Last. Wenden Sie eine geeignete Back-Off-Strategie an, wenn Wiederholungsverzögerungen zunimmt.
Drosselung Steuert den Verbrauch von Ressourcen, die von Anwendungskomponenten verwendet werden, und schützt sie vor überlasteten Ressourcen. Wenn eine Ressource einen Auslastungsschwellenwert erreicht, verschiebt sie Vorgänge mit niedrigerer Priorität und beeinträchtigt nicht wesentliche Funktionen, sodass die wesentliche Funktionalität fortgesetzt werden kann, bis genügend Ressourcen verfügbar sind, um zum normalen Betrieb zurückzukehren.

Hier sind einige zusätzliche Empfehlungen:

  • Verwenden Sie vom Anbieter bereitgestellte SDKs, z. B. azure SDKs, um eine Verbindung mit abhängigen Diensten herzustellen. Verwenden Sie integrierte Resilienzfunktionen, anstatt benutzerdefinierte Funktionen zu implementieren.

  • Wenden Sie eine geeignete Back-Off-Strategie an, wenn Sie fehlgeschlagene Abhängigkeitsaufrufe wiederholen, um ein selbstverschuldetes DDoS-Szenario zu vermeiden.

  • Definieren Sie allgemeine Technische Kriterien für alle Microserviceteams für Anwendungen, um die Konsistenz und Geschwindigkeit bei der Verwendung von Resilienzmustern auf Anwendungsebene zu erhöhen.

  • Implementieren Sie Resilienzmuster mithilfe bewährter standardisierter Pakete wie Polly für C# oder Sentinel für Java.

  • Verwenden Sie Korrelations-IDs für alle Ablaufverfolgungsereignisse und Protokollmeldungen, um sie mit einer bestimmten Anforderung zu verknüpfen. Geben Sie nicht nur bei Anforderungen, bei denen ein Fehler aufgetreten ist, sondern bei allen Aufrufen Korrelations-IDs zurück.

  • Verwenden Sie die strukturierte Protokollierung für alle Protokollmeldungen. Wählen Sie eine einheitliche Betriebsdatensenke für Anwendungsablaufverfolgungen, Metriken und Protokolle aus, damit Operatoren Problemlos Probleme debuggen können. Weitere Informationen finden Sie unter Sammeln, Aggregieren und Speichern von Überwachungsdaten für Cloudanwendungen.

  • Stellen Sie sicher, dass Betriebsdaten zusammen mit geschäftlichen Anforderungen verwendet werden, um ein Anwendungsintegritätsmodell zu informieren.

Programmierspracheauswahl

Es ist wichtig, die richtigen Programmiersprachen und Frameworks auszuwählen. Diese Entscheidungen werden häufig von den Fähigkeiten oder standardisierten Technologien in der organization bestimmt. Es ist jedoch von entscheidender Bedeutung, die Leistung, Resilienz und die allgemeinen Funktionen verschiedener Sprachen und Frameworks zu bewerten.

Überlegungen zum Entwurf

  • Development Kit-Funktionen. Es gibt Unterschiede in den Funktionen, die von Azure-Dienst-SDKs in verschiedenen Sprachen angeboten werden. Diese Unterschiede können ihre Wahl eines Azure-Diensts oder einer Programmiersprache beeinflussen. Wenn Beispielsweise Azure Cosmos DB eine praktikable Option ist, ist Go möglicherweise keine geeignete Entwicklungssprache, da es kein First-Party-SDK gibt.

  • Featureupdates. Überlegen Sie, wie oft das SDK mit neuen Features für die ausgewählte Sprache aktualisiert wird. Häufig verwendete SDKs wie .NET- und Java-Bibliotheken werden häufig aktualisiert. Andere SDKs oder SDKs für andere Sprachen werden möglicherweise weniger häufig aktualisiert.

  • Mehrere Programmiersprachen oder Frameworks. Sie können mehrere Technologien verwenden, um verschiedene zusammengesetzte Workloads zu unterstützen. Sie sollten jedoch Eine Zersiedelung vermeiden, da dies verwaltungskomplexe und operative Herausforderungen mit sich bringt.

  • Computeoption. Legacy- oder proprietäre Software wird möglicherweise nicht in PaaS-Diensten ausgeführt. Außerdem können Sie möglicherweise keine legacy- oder proprietäre Software in Container einschließen.

Entwurfsempfehlungen

  • Bewerten Sie alle relevanten Azure SDKs für die benötigten Funktionen und die von Ihnen ausgewählten Programmiersprachen. Überprüfen Sie die Ausrichtung mit nicht funktionalen Anforderungen.

  • Optimieren Sie die Auswahl von Programmiersprachen und Frameworks auf Microserviceebene. Verwenden Sie nach Bedarf mehrere Technologien.

  • Priorisieren Sie das .NET SDK, um Zuverlässigkeit und Leistung zu optimieren. .NET Azure SDKs bieten in der Regel mehr Funktionen und werden häufig aktualisiert.

Nächster Schritt

Sehen Sie sich die Überlegungen für die Anwendungsplattform an.