(0) exportieren Drucken
Alle erweitern

Methoden zum Maximieren der Skalierbarkeit und Wirtschaftlichkeit von warteschlangenbasierten Messaging-Lösungen unter Azure

Letzte Aktualisierung: Juli 2014

Autoren: Amit Srivastava

Überprüfung: Brad Calder, Sidney Higa, Christian Martinez, Steve Marx, Curt Peterson, Paolo Salvatori und Trace Young

Dieser Artikel ist ein normativer Leitfaden mit Best Practices zum Erstellen warteschlangenbasierter Messaginglösungen auf der Azure-Plattform, die skalierbar, hoch effizient und kosteneffektiv sind. Dieser Artikel richtet sich an Lösungsarchitekten und -entwickler, die Cloud-basierte Lösungen entwerfen und implementieren, die die Warteschlangen-Speicherdienste der Azure-Plattform nutzen.

Eine herkömmliche warteschlangenbasierte Messaginglösung verwendet das Konzept des Nachrichtenspeicherorts, das als Nachrichtenwarteschlange bezeichnet wird. Dabei handelt es sich um ein Repository für Daten, die an Teilnehmer gesendet oder von diesen empfangen werden – in der Regel mithilfe eines asynchronen Kommunikationsmechanismus.

In diesem Artikel wird untersucht, wie Entwickler bestimmte Entwurfsmuster in Verbindung mit Funktionen nutzen können, die von der Azure-Plattform bereitgestellt werden, um optimierte und kostengünstige warteschlangenbasierte Messaginglösungen zu erstellen. Der Artikel bietet einen tieferen Einblick in häufig verwendete Ansätze zum Implementieren von warteschlangenbasierten Interaktionen in Azure-Lösungen und enthält Empfehlungen zum Verbessern der Leistung, Erhöhen der Skalierbarkeit und Reduzieren der Betriebsausgaben.

Die zugrunde liegende Erläuterung wird durch relevante Best Practices, Hinweise und Empfehlungen ergänzt. Das in diesem Artikel beschriebene Szenario behandelt eine technische Implementierung, die auf einem Kundenprojekt aus der Praxis basiert.

Eine typische Messaginglösung für den Datenaustausch zwischen den verteilten Komponenten mithilfe von Nachrichtenwarteschlangen umfasst Verleger, die Nachrichten in Warteschlangen einreihen, und einen oder mehrere Abonnenten, für den bzw. die die Nachrichten gedacht sind. In den meisten Fällen werden die Abonnenten, die manchmal auch als Warteschlangenlistener bezeichnet werden, als Single- oder Multithreadprozesse implementiert, die gemäß einem Zeitplan nach Bedarf fortlaufend ausgeführt oder initiiert werden.

Auf höherer Ebene gibt es zwei primäre Verteilungsmechanismen, mit denen ein Warteschlangenlistener die in einer Warteschlange gespeicherten Nachrichten empfangen kann:

  • Abrufen (PULL-basiertes Modell): Ein Listener überwacht eine Warteschlange, indem er die Warteschlange regelmäßig auf neue Nachrichten hin überprüft. Wenn die Warteschlange leer ist, setzt der Listener das Abrufen der Warteschlange fort, wobei er in regelmäßigen Abständen in den Energiesparmodus übergeht, und der Abrufvorgang dadurch unterbrochen wird.

  • Auslösen (PUSH-basiertes Modell): Ein Listener abonniert ein Ereignis, das ausgelöst wird (entweder vom Verleger selbst oder von einem Warteschlangendienst-Manager), wenn eine Nachricht in einer Warteschlange eingeht. Der Listener kann dann die Nachrichtenverarbeitung initiieren, sodass er nicht die Warteschlange abrufen muss, um festzustellen, ob neue Arbeitsaufgaben verfügbar sind.

Es sollte auch erwähnt werden, dass es von beiden Mechanismen unterschiedliche Arten gibt. Beispielsweise kann das Abrufen blockierend und nicht blockierend sein. Eine blockierende Anforderung wird in eine Wartestellung versetzt, bis eine neue Nachricht in der Warteschlange eingeht (oder ein Timeout auftritt). Dagegen wird eine nicht blockierende Anforderung vollständig durchgeführt, auch wenn die Warteschlange leer ist. Wenn das Auslösen verwendet wird, kann eine Benachrichtigung an die Warteschlangenlistener weitergegeben werden, wenn eine neue Nachricht eingeht, nur wenn die erste Nachricht in einer leeren Warteschlange eingeht oder wenn die Warteschlangentiefe eine bestimmte Ebene erreicht.

noteHinweis
Die Vorgänge, die Elemente aus der Warteschlange entfernen und die von der Warteschlangendienst-API von Azure unterstützt werden, sind nicht blockierend. Das bedeutet, dass API-Methoden wie z. B. GetMessage oder GetMessages sofort zurückgegeben werden, wenn in einer Warteschlange keine Nachrichten gefunden werden. Im Gegensatz dazu bieten Azure Service Bus-Warteschlangen blockierende Empfangsvorgänge, die den aufrufenden Thread blockieren, bis eine Nachricht in einer Warteschlange eingeht oder ein angegebenes Timeout abgelaufen ist.

Die nachfolgende Zusammenfassung beschreibt, wie heute am häufigsten an das Implementieren von Warteschlangenlistenern in Azure-Lösungen herangegangen wird:

  1. Ein Listener wird als Anwendungskomponente implementiert, die als Teil einer Workerrolleninstanz instanziiert und ausgeführt wird.

  2. Der Lebenszyklus der Warteschlangenlistener-Komponente ist häufig an die Laufzeit der Hostingrolleninstanz gebunden.

  3. Die wesentliche Verarbeitungslogik besteht aus einer Schleife, in der Nachrichten aus der Warteschlange entfernt und für die Verarbeitung verteilt werden.

  4. Wenn keine Nachrichten empfangen werden, geht der Listening-Thread in einen Energiesparmodus über, dessen Dauer häufig durch einen anwendungsspezifischen Backoffalgorithmus gesteuert wird.

  5. Die Empfangsschleife wird ausgeführt und eine Warteschlange wird abgerufen, bis der Listener benachrichtigt wird, die Schleife und den Vorgang zu beenden.

Das folgende Flussdiagramm stellt die Logik dar, die häufig verwendet wird, wenn ein Warteschlangenlistener mit einem Abrufmechanismus in Azure-Anwendungen implementiert wird:

Best Practices für Messaginglösungen Azure2
noteHinweis
Im Rahmen dieses Artikels werden keine komplexeren Entwurfsmuster – beispielsweise Muster, die einen zentralen Warteschlangen-Manager (Broker) erfordern – verwendet.

Die Verwendung eines klassischen Warteschlangenlisteners mit einem Abrufmechanismus ist möglicherweise nicht die optimale Wahl bei Azure-Warteschlangen, da das Azure-Preismodell Speichertransaktionen in Form von Anwendungsanforderungen misst, die für die Warteschlange, unabhängig davon, ob sie leer ist oder nicht, ausgeführt werden. In den nächsten Abschnitten werden verschiedene Techniken zum Maximieren der Leistung und Minimieren der Kosten für warteschlangenbasierte Messaginglösungen auf der Azure-Plattform erläutert.

In diesem Abschnitt wird überprüft, wie die relevanten Entwurfsaspekte verbessert werden können, um höhere Leistung, bessere Skalierbarkeit und Kosteneffizienz zu erreichen.

Die einfachste Methode, um zu ermitteln, ob ein Implementierungsmuster eine "effizientere Lösung" darstellt, besteht vermutlich darin, festzustellen, ob der Entwurf die folgenden Zielsetzungen erfüllt:

  • Reduziert Betriebsausgaben, indem ein beträchtlicher Teil der Speichertransaktionen entfernt wird, aus denen sich keine verwendbaren Arbeitsaufgaben ableiten lassen.

  • Eliminiert übermäßige Latenzzeit, die durch ein Abrufintervall auferlegt wird, wenn eine Warteschlange auf neue Nachrichten hin überprüft wird.

  • Skaliert dynamisch aufwärts und abwärts, indem die Rechenleistung an veränderliche Arbeitsmengen angepasst wird.

Das Implementierungsmuster sollte diese Ziele auch erreichen, ohne die Komplexität in einem Maß zu erhöhen, das durch die verbundenen Vorteile nicht gerechtfertigt ist.

Bei der Beurteilung der Gesamtkosten (TCO) und Rendite (ROI) für eine Lösung, die auf der Azure-Plattform bereitgestellt wird, stellt die Menge der Speichertransaktionen eine der wichtigsten Variablen in der TCO-Gleichung dar. Eine Verringerung der Anzahl von Transaktionen in Verbindung mit Azure-Warteschlangen reduziert die Betriebskosten, da diese mit dem Ausführen von Lösungen auf Azure in Beziehung stehen.

Die mit der Azure-Warteschlange einhergehenden Speicherplatzkosten können wie folgt berechnet werden –

Warteschlangenplatz: 24 Bytes + Länge(Warteschlangenname) * 2 +  Für jedes Metadatum(4 Bytes + Länge(Warteschlangenname) * 2 Bytes + Länge(Wert) * 2 Bytes)

Nachrichtenplatz: 12 Bytes + Länge(Nachricht)

Im Kontext einer warteschlangenbasierten Messaginglösung kann die Anzahl der Speichertransaktionen über eine Kombination aus den folgenden Methoden reduziert werden:

  1. Wenn Sie Nachrichten in einer Warteschlange einreihen, gruppieren Sie zusammengehörige Nachrichten in einem einzigen größeren Batch, komprimieren und speichern Sie das komprimierte Bild in einem BLOB-Speicher, und verwenden Sie die Warteschlange als Referenz auf das BLOB, das die tatsächlichen Daten enthält. Dieser Ansatz hilft beim Optimieren von Transaktionskosten und Speicherplatzkosten.

  2. Wenn Sie Nachrichten aus einer Warteschlange abrufen, gruppieren Sie mehrere Nachrichten in einem Batch in einer einzelnen Speichertransaktion. Mit der GetMessages-Methode in der Warteschlangendienst-API kann die angegebene Anzahl von Nachrichten in einer einzelnen Transaktion aus der Warteschlange entfernt werden (siehe Hinweis unten).

  3. Wenn Se das Vorhandensein von Arbeitsaufgaben in einer Warteschlange überprüfen, vermeiden Sie aggressive Abrufintervalle, und implementieren Sie eine Backoffverzögerung, die die Zeitdauer zwischen Abrufanforderungen erhöht, wenn die Warteschlange kontinuierlich leer bleibt.

  4. Reduzieren Sie die Anzahl der Warteschlangenlistener – verwenden Sie bei einem PULL-basierten Modell nur einen Warteschlangenlistener pro Rolleninstanz, wenn die Warteschlange leer ist. Um die Anzahl von Warteschlangenlistenern pro Rolleninstanz noch weiter auf Null (0) zu reduzieren, verwenden Sie einen Benachrichtigungsmechanismus, um Warteschlangenlistener zu instanziieren, wenn die Warteschlange Arbeitsaufgaben empfängt.

  5. Wenn Warteschlangen die meiste Zeit leer bleiben, skalieren Sie die Anzahl der Rolleninstanzen automatisch abwärts, und setzen Sie die Überwachung relevanter Systemmetriken fort, um zu bestimmen, ob und wann die Anwendung die Anzahl der Instanzen aufwärts skalieren sollte, um zunehmende Arbeitslasten bewältigen zu können.

  6. Implementieren eines Mechanismus zum Entfernen von nicht verarbeiteten Nachrichten. Dabei handelt es sich normalerweise um nicht wohlgeformte Nachrichten, die von der Anwendung nicht verarbeitet werden können. Wenn sie unverarbeitet bleiben, können sich solche Nachrichten ansammeln und wiederholt Transaktions- und Verarbeitungskosten verursachen. Ein einfacher Implementierungsmechanismus könnte darin bestehen, dass alle Nachrichten, die älter als ein eingegebener Schwellenwert sind, aus der Warteschlange entfernt und zur weiteren Auswertung in ein Archivsystem geschrieben werden.

  7. Verringern der erwarteten Fehler wegen Zeitlimitüberschreitungen. Wenn Sie eine Anforderung an den Dienst senden, können Sie Ihren Timeout angeben und ihn kleiner als den Wert von SLA-Timeout festlegen. In diesen Szenario wird die Anforderung beim Erreichen des Timeouts als erwarteter Timeout klassifiziert und als abzurechnende Transaktion gezählt.

Die meisten der oben erwähnten Empfehlungen können in eine relativ allgemeine Implementierung übersetzt werden, die Nachrichtenbatches verarbeitet und viele der zugrunde liegenden Warteschlangen-/BLOB-Speicher und Threadverwaltungsvorgänge kapselt. Die entsprechende Vorgehensweise wird an einer späteren Stelle in diesem Artikel untersucht.

ImportantWichtig
Beim Abrufen von Nachrichten über die GetMessages-Methode ist die maximale Batchgröße, die von der Warteschlangendienst-API in einem einzelnen Vorgang zum Entfernen von Elementen aus der Warteschlange unterstützt wird, auf 32 beschränkt.

Im Allgemeinen steigen die Kosten von Azure-Warteschlangentransaktionen linear, wenn die Anzahl der Warteschlangendienst-Clients zunimmt – wenn z. B. die Anzahl der Rolleninstanzen aufwärts skaliert wird oder die Anzahl von Threads zum Entfernen von Elementen aus der Warteschlange erhöht wird. Das folgende Beispiel, das auf konkreten Zahlen basiert, veranschaulicht, welche Auswirkungen ein Lösungsentwurf, in dem die oben genannten Empfehlungen nicht umgesetzt sind, auf die Kosten auswirken kann.

Wenn der Lösungsarchitekt keine relevanten Optimierungen implementiert, werden durch die oben beschriebene Abrechnungssystemarchitektur mit großer Wahrscheinlichkeit übermäßig hohe Betriebskosten verursacht, wenn die Lösung auf der Azure-Plattform bereitgestellt und ausgeführt wird. Die Ursachen für die möglicherweise übermäßig hohen Kosten werden in diesem Abschnitt beschrieben.

Wie in der Szenariodefinition erwähnt, gehen die Daten zu geschäftlichen Transaktionen regelmäßig ein. Wir gehen jedoch davon aus, dass die Lösung nur während 25 % eines normalen achtstündigen Geschäftstags mit der Verarbeitung von Arbeitslasten beschäftigt ist. Das ergibt eine "Leerlaufzeit" von 6 Stunden (8 Stunden * 75 %), in der möglicherweise keine Transaktionen durch das System weitergeleitet werden. Darüber hinaus empfängt die Lösung überhaupt keine Daten während der 16 Stunden eines jeden Tags, die keine Geschäftsstunden sind.

Auch in dem Leerlaufzeitraum von insgesamt 22 Stunden versucht die Lösung, Arbeitsaufgaben aus der Warteschlange zu entfernen, da nicht bekannt ist, wann neue Daten eingehen. In diesem Zeitfenster führt jeder einzelne Thread zum Entfernen von Elementen aus der Warteschlange bis zu 79.200 Transaktionen (22 Stunden * 60 Minuten * 60 Transaktionen/Minute) für eine Eingabewarteschlange aus, wenn ein standardmäßiges Abrufintervall von 1 Sekunde angenommen wird.

Wie bereits erwähnt wurde, basiert das Preismodell auf der Azure-Plattform auf einzelnen "Speichertransaktionen". Eine Speichertransaktion ist eine Anforderung einer Benutzeranwendung, um Speicherdaten hinzuzufügen, zu lesen, zu aktualisieren oder zu löschen. Zum Zeitpunkt, als dieses Whitepaper verfasst wird, werden Speichertransaktionen mit einer Rate von 0,01 USD pro 10.000 Transaktionen berechnet (hierbei sind keine Werbeangebote oder besondere Preisvereinbarungen berücksichtigt).

ImportantWichtig
Wenn Sie die Anzahl der Warteschlangentransaktionen berechnen, beachten Sie, dass das Einreihen einer einzelnen Nachricht in eine Warteschlange als eine Transaktion gezählt wird, das Abrufen einer Nachricht jedoch oft ein Prozess mit zwei Schritten ist, in dem das Abrufen von einer Anforderung gefolgt wird, die Nachricht aus der Warteschlange zu entfernen. Infolgedessen ist ein erfolgreicher Vorgang zum Entfernen von Elementen aus der Warteschlange mit zwei Speichertransaktionen verbunden. Beachten Sie, dass auch eine Anforderung zum Entfernen von Elementen aus der Warteschlange, bei der keine Daten abgerufen werden, als abrechenbare Transaktion gezählt wird.

Die Speichertransaktionen, die im Szenario oben von einem einzelnen Thread zum Entfernen von Elementen aus der Warteschlange generiert werden, erhöhen die monatliche Rechnung um ungefähr 2,38 USD (79.200 / 10.000 * 0,01 USD * 30 Tage). Bei 200 Threads zum Entfernen von Elementen aus der Warteschlange (oder alternativ 1 entsprechenden Thread in 200 Workerrolleninstanzen) erhöhen sich die Kosten um 457,20 USD pro Monat. Diese Kosten wurden verursacht, obwohl die Lösung keine Berechnungen ausgeführt hat, sondern nur überprüft hat, ob in den Warteschlangen Arbeitsaufgaben verfügbar sind. Bei dem obigen Szenario handelt es sich um ein abstraktes Beispiel, da der Dienst nie auf diese Weise implementiert werden würde. Aus diesem Grund ist es wichtig, die als Nächstes beschriebenen Optimierungen umzusetzen.

Ein Ansatz zum Optimieren der Leistung von warteschlangenbasierten Azure-Messaginglösungen besteht darin, die Veröffentlichungs-/Abonnement-Messagingschicht zu verwenden, die mit Azure Service Bus bereitgestellt wird, wie in diesem Abschnitt beschrieben ist.

Bei dieser Vorgehensweise müssen sich Entwickler auf das Erstellen einer Kombination aus Abrufvorgängen und PUSH-basierten Echtzeitbenachrichtigungen konzentrieren, damit die Listener ein Benachrichtigungsereignis (Trigger) abonnieren können, das bei bestimmten Bedingungen ausgelöst wird und anzeigt, dass eine neue Arbeitslast in der Warteschlange eingegangen ist. Dieser Ansatz erweitert die herkömmliche Warteschlangen-Abrufschleife mit einer Veröffentlichungs-/Abonnement-Messagingschicht zum Verteilen von Benachrichtigungen.

In einem komplexen verteilten System würde dieser Ansatz die Verwendung eines "Nachrichtenbusses" oder von "nachrichtenbezogener Middleware" erfordern, um eine lose verbundene Übertragung der Benachrichtigungen an einen oder mehrere Abonnenten sicherzustellen. Azure Service Bus ist eine gute Wahl, um auf die Messaginganforderungen von lose verbundenen verteilten Anwendungsdiensten einzugehen, die auf Azure und am lokalen Standort ausgeführt werden. Azure Service Bus ist auch ideal für eine "Nachrichtenbus"-Architektur, die den Austausch von Benachrichtigungen zwischen Prozessen ermöglicht, die Teil einer warteschlangenbasierten Kommunikation sind.

Die Prozesse, die während eines warteschlangenbasierten Nachrichtenaustauschs durchgeführt werden, können das folgende Muster nutzen:

Best Practices für Messaginglösungen Azure3

Insbesondere in Bezug auf die Interaktion zwischen Warteschlangendienst-Verlegern und -Abonnenten erfüllen dieselben Prinzipien, die für die Kommunikation zwischen Azure-Rolleninstanzen gelten, die meisten Anforderungen an den Nachrichtenaustausch mit PUSH-basierter Benachrichtigung.

ImportantWichtig
Für die Verwendung von Azure Service Bus gilt ein Preismodell, das die Menge der Messagingvorgänge im Zusammenhang mit einer Service Bus-Messagingentität, wie z. B. einer Warteschlange oder eines Themas, berücksichtigt.

Aus diesem Grund ist eine Kosten-Nutzen-Analyse wichtig, um die Vorteile und Nachteile zu beurteilen, die die Implementierung von Service Bus in einer bestimmten Architektur mit sich bringt. In diesem Zusammenhang empfiehlt sich auch eine Auswertung, ob die Implementierung einer Schicht zum Verteilen von Benachrichtigungen, die auf Service Bus basiert, tatsächlich eine Kostensenkung ermöglicht, die die Investition und den zusätzlichen Entwicklungsaufwand rechtfertigt.

Weitere Informationen zum Preismodell für Service Bus finden Sie in den relevanten Abschnitten unter FAQ für Azure.

Mit einer Veröffentlichungs-/Abonnement-Messagingschicht ist es relativ einfach, den Auswirkungen auf die Latenzzeit entgegenzuwirken. Sie können die Kosten jedoch noch weiter senken, wenn Sie die dynamische (flexible) Skalierung verwenden, wie im nächsten Abschnitt beschrieben ist.

Für Azure-Speicher sind Skalierbarkeitsziele zusammenfassend auf der Ebene des Kontos sowie auf Partitionsebene definiert. Eine Warteschlange stellt in Azure eine eigene, einzelne Partition dar und kann daher bis zu 2000 Nachrichten pro Sekunde verarbeiten. Wenn die Anzahl der Nachrichten dieses Kontingent übersteigt, antwortet der Speicherdienst mit der Nachricht HTTP 503 Server ausgelastet. Diese Nachricht zeigt an, dass die Plattform eine Drosselung der Warteschlange vornimmt. Anwendungsentwickler sollten Kapazitätsplanung durchführen, um sicherzustellen, dass die Anforderungsrate der Anwendung von einer passenden Anzahl Warteschlangen verarbeitet werden kann. Wenn eine einzelne Warteschlange die Anforderungsrate einer Anwendung nicht verarbeiten kann, entwerfen Sie eine partitionierte Warteschlangenarchitektur mit mehreren Warteschlangen, um die Skalierbarkeit sicherzustellen.

Eine Anwendung sollte darüber hinaus mehrere verschiedene Warteschlangen für verschiedene Nachrichtentypen nutzen. Dies stellt die Skalierbarkeit der Anwendung sicher, da mehrere Warteschlangen koexistieren können, ohne dass eine einzelne Warteschlange "abgewürgt" wird. Damit wird außerdem eine diskrete Steuerung der Warteschlangenverarbeitung auf der Basis der Vertraulichkeit und Priorität von Nachrichten, die in verschiedenen Warteschlangen gespeichert sind, möglich. Warteschlangen mit hoher Priorität sollten mehr Arbeitsprozesse zugeordnet werden als Warteschlangen mit geringer Priorität.

Die Azure-Plattform ermöglicht es den Kunden, schneller und einfacher als je zuvor aufwärts und abwärts zu skalieren. Die Möglichkeit der Anpassung an variable Arbeitslasten und variablen Datenverkehr ist einer der primären Wertvorschläge der Cloud-Plattform. Das bedeutet, dass "Skalierbarkeit" kein mit hohen Kosten verbundener IT-Begriff mehr ist, sondern eine Standardfunktion, die programmgesteuert und nach Bedarf in einer gut geplanten Cloud-Lösung aktiviert werden kann.

Dynamische Skalierung bezeichnet im technischen Sinn die Anpassungsfähigkeit einer bestimmten Lösung an sich ständig wechselnde Arbeitslasten, indem Kapazität und Verarbeitungsleistung während der Laufzeit erhöht und reduziert werden. Die Azure-Plattform unterstützt die dynamische Skalierung systemintern durch die Bereitstellung einer verteilten Computinginfrastruktur, die den Erwerb von Computingstunden nach Bedarf ermöglicht.

Es ist wichtig, zwischen den beiden folgenden Typen der dynamischen Skalierung auf der Azure-Plattform zu unterscheiden:

  • Rolleninstanzskalierung bezieht sich auf das Hinzufügen und Entfernen von zusätzlichen Web- oder Workerrolleninstanzen, um die Arbeitslasten zu einem bestimmten Zeitpunkt bewältigen zu können. Zu diesem Zweck wird oft die Anzahl der Instanzen in der Dienstkonfiguration geändert. Die Erhöhung der Instanzenzahl bewirkt, dass die Azure-Laufzeit neue Instanzen startet, während das Reduzieren der Instanzenzahl dazu führt, dass Instanzen beendet werden.

  • Prozessskalierung (Threadskalierung) bezieht sich auf die Bewahrung von ausreichender Kapazität im Hinblick auf die Verarbeitung von Threads in einer bestimmten Rolleninstanz, indem die Anzahl der Threads abhängig von der aktuellen Arbeitsauslastung nach oben oder unten angepasst wird.

Für die dynamische Skalierung in einer warteschlangenbasierten Messaginglösung gilt eine Kombination aus den folgenden allgemeinen Empfehlungen:

  1. Überwachen der Leistungskennzahlen – dazu gehören CPU-Auslastung, Warteschlangentiefe, Antwortzeiten und Nachrichtenverarbeitungs-Latenzzeit.

  2. Dynamisches Erhöhen oder Verringern der Anzahl von Rolleninstanzen, um vorhersagbare oder nicht vorhersagbare Arbeitsspitzenlasten handhaben zu können.

  3. Programmgesteuertes Erweitern und Reduzieren der Anzahl von Verarbeitungsthreads, um eine Anpassung an die jeweilige Auslastung einer bestimmten Rolleninstanz zu ermöglichen.

  4. Gleichzeitiges Partitionieren und Verarbeiten von differenzierten Arbeitslasten unter Verwendung der Task Parallel Library in .NET Framework 4.

  5. Bewahren einer geeigneten Kapazität in Lösungen mit sehr veränderlichen Arbeitslasten, damit plötzlich auftretende Spitzenlasten ohne den Mehraufwand, der durch die Einrichtung zusätzlicher Instanzen verursacht wird, bewältigt werden können.

Mithilfe der Dienstverwaltungs-API kann ein von Azure gehosteter Dienst die Anzahl der ausgeführten Rolleninstanzen durch die Änderung der Bereitstellungskonfiguration während der Laufzeit ändern.

noteHinweis
Die maximale Anzahl von kleinen Azure-Serverinstanzen (oder die entsprechende Anzahl von Serverinstanzen anderer Größe hinsichtlich der Anzahl von Kernen) ist in einem typischen Abonnement standardmäßig auf 20 beschränkt. Alle Anfragen, die eine Erhöhung des Kontingents betreffen, sollten an das Azure-Supportteam gerichtet werden. Weitere Informationen finden Sie unter FAQ für Azure.

Dank der Einführung der Automatischen Skalierung in Azure kann die Plattform die Instanzenanzahl hoch- oder herunterskalieren, abhängig von der Nachrichtentiefe der Warteschlange. Das ist ein sehr natürliches Maß für die dynamische Skalierung. Der zusätzliche Vorteil besteht darin, dass die Azure-Plattform Aufgaben für die Anwendung überwacht und skaliert.

Die dynamische Skalierung der Anzahl von Rolleninstanzen ist nicht immer die am besten geeignete Methode für den Umgang mit Spitzenlasten. Beispielsweise kann es einige Sekunden dauern, eine neue Rolleninstanz zu erstellen, und zu diesem Zeitpunkt gibt es keine SLA-Metriken in Bezug auf die Erstellungsdauer. Stattdessen kann eine Lösung einfach die Anzahl der Arbeitsthreads erhöhen, um die veränderliche Zunahme der Arbeitslasten zu bewältigen. Während die Arbeitslasten verarbeitet werden, überwacht die Lösung die relevanten Lastmetriken und ermittelt, ob sie die Anzahl der Arbeitsprozesse dynamisch erhöhen oder reduzieren muss.

ImportantWichtig
Derzeit ist das Skalierbarkeitsziel für eine einzelne Azure-Warteschlange auf 2000 Transaktionen pro Sekunde beschränkt. Wenn eine Anwendung versucht, diesen Zielwert zu überschreiten, beispielsweise indem Warteschlangenvorgänge von mehreren Rolleninstanzen mit Hunderten von Threads zum Entfernen von Elementen aus der Warteschlange durchgeführt werden, wird möglicherweise die Antwort "HTTP 503 Server ausgelastet" vom Speicherdienst zurückgegeben. In so einem Fall sollte die Anwendung einen Wiederholungsmechanismus mit einem exponentiellen Backoffverzögerungs-Algorithmus implementieren. Wenn die HTTP 503-Fehler regelmäßig auftreten, wird jedoch empfohlen, mehrere Warteschlangen zu verwenden und eine auf Partitionierung basierende Strategie zu implementieren, um die Skalierung über mehrere Warteschlangen hinweg zu ermöglichen.

In den meisten Fällen liegt die automatische Skalierung im Verantwortungsbereich einer einzelnen Rolleninstanz. Dagegen umfasst die Rolleninstanzskalierung häufig ein zentrales Element der Lösungsarchitektur, das für die Überwachung der Leistungsmetriken und das Ausführen der entsprechenden Skalierungsmaßnahmen zuständig ist. Das Diagramm unten zeigt eine Dienstkomponente mit der Bezeichnung Dynamic Scaling Agent, die die Lastmetriken erfasst und analysiert, um zu ermitteln, ob neue Instanzen bereitgestellt oder Instanzen im Leerlauf beendet werden sollen.

Best Practices für Messaginglösungen Azure4

Beachten Sie, dass der Skalierungsagentdienst als Workerrolle, die auf Azure ausgeführt wird, oder als lokaler Dienst bereitgestellt werden kann. Ungeachtet der Bereitstellungstopologie kann der Dienst auf die Azure-Warteschlangen zugreifen.

Um eine dynamische Skalierungsfunktion zu implementieren, ziehen Sie die Verwendung des Microsoft Enterprise Library-Anwendungsblocks für automatische Skalierung in Erwägung, der automatisches Skalierungsverhalten in Lösungen ermöglicht, die auf Azure ausgeführt werden. Der Anwendungsblock für automatische Skalierung stellt alle Funktionen bereit, die zum Definieren und Überwachen der automatischen Skalierung in einer Azure-Anwendung erforderlich sind.

noteHinweis
Erwägen Sie als Alternative zur manuellen dynamischen Skalierung das Feature integrierte automatische Skalierung in Azure einzusetzen.

Nachdem wir die Auswirkungen auf die Latenzzeit, die Speichertransaktionskosten und die Anforderungen der dynamischen Skalierung untersucht haben, sollten wir die Empfehlungen in einer technischen Implementierung konsolidieren.

Das folgende konkrete Beispiel basiert auf einem verallgemeinerten Kundenszenario aus der Praxis.

Ein Anbieter von SaaS-Lösungen führt ein neues Abrechnungssystem ein, das als Azure-Anwendung implementiert ist und die Geschäftsanforderungen bei der Verarbeitung von Kundentransaktionen bedarfsgerecht erfüllt. Die Schlüsselvoraussetzung der Lösung dreht sich um die Fähigkeit, rechenintensive Arbeitslasten in die Cloud auszulagern und die Flexibilität der Azure-Infrastruktur zu nutzen, um die rechenintensiven Vorgänge auszuführen.

Das lokale Element der End-to-End-Architektur konsolidiert und verteilt große Mengen von Transaktionen in einem von Azure gehosteten Dienst in regelmäßigen Abständen während des ganzen Tags. Pro Übermittlung werden zwischen einigen Tausenden und Hunderttausenden von Transaktionen und pro Tag Millionen von Transaktionen gesendet. Darüber hinaus wird angenommen, dass die Lösung eine SLA-basierte Anforderung nach garantierter maximaler Verarbeitungslatenzzeit erfüllen muss.

Die Lösungsarchitektur basiert auf dem verteilten MapReduce-Entwurfsmuster. Sie umfasst eine workerrollenbasierte Cloud-Ebene mit mehreren Instanzen, wobei der Azure-Warteschlangenspeicher für die Arbeitsverteilung verwendet wird. Transaktionsbatches werden von der Prozessinitiator-Workerrolleninstanz empfangen, in kleinere Arbeitsaufgaben zerlegt und zum Zweck der Lastenverteilung in eine Sammlung von Azure-Warteschlangen eingereiht.

Die Arbeitslastverarbeitung wird von mehreren Instanzen der Verarbeitungsworkerrolle gehandhabt, die Arbeitsaufgaben von Warteschlangen abrufen und durch die Berechnungsprozeduren leiten. Zur Leistungsoptimierung implementieren die Verarbeitungsinstanzen mithilfe von Multithread-Warteschlangenüberwachung eine parallele Datenverarbeitung.

Die verarbeiteten Arbeitsaufgaben werden in eine dedizierte Warteschlange weitergeleitet, aus der sie von der Prozesscontroller-Workerrolleninstanz wieder entfernt werden. Anschließend werden sie in einem Datenspeicher für Data Mining, Berichterstellung und Analyse aggregiert und permanent gespeichert.

Die Lösungsarchitektur kann wie folgt dargestellt werden:

AzureGuidance_MaxScale

Das Diagramm oben zeigt eine typische Architektur für das horizontale Skalieren von großen oder komplexen Berechnungsarbeitslasten. Das von dieser Architektur übernommene warteschlangenbasierte Nachrichtenaustauschmodell ist auch für viele andere Azure-Anwendungen und -Dienste typisch, die für die Kommunikation Warteschlangen verwenden müssen. Dadurch wird ein kanonischer Ansatz für die Untersuchung von bestimmten wesentlichen Komponenten, die bei einem warteschlangenbasierten Nachrichtenaustausch beteiligt sind, ermöglicht.

Um die Effizienz und die Wirtschaftlichkeit von warteschlangenbasierten Messaginglösungen zu maximieren, die auf der Azure-Plattform ausgeführt werden, sollten Lösungsarchitekten und -entwickler die folgenden Empfehlungen beachten.

Lösungsarchitekten sollten Folgendes beachten:

  • Stellen Sie eine warteschlangenbasierte Messagingarchitektur bereit, die den Azure-Warteschlangenspeicherdienst für hoch skalierbare, asynchrone Kommunikation zwischen Ebenen und Diensten in Cloud-basierten oder Hybridlösungen verwendet.

  • Empfehlen Sie eine partitionierte Warteschlangenarchitektur, die eine Skalierung auf mehr als 2000 Nachrichten/Sekunde unterstützt.

  • Machen Sie sich mit den Grundlagen des Azure-Preismodells vertraut, und optimieren Sie die Lösung zur Reduzierung der Transaktionskosten mithilfe einer Reihe von Best Practices und Entwurfsmustern.

  • Berücksichtigen Sie die Anforderungen an die dynamische Skalierung, indem Sie eine Architektur bereitstellen, die an veränderliche und ständig wechselnde Arbeitslasten angepasst werden kann.

  • Nutzen Sie die richtigen Techniken und Ansätze für die automatische Skalierung, um die Rechenleistung flexibel zu erhöhen und zu reduzieren und die Betriebsausgaben dadurch noch weiter zu optimieren.

  • Bewerten Sie die automatische Skalierung in Azure, um festzustellen, ob sie den Anforderungen Ihrer Anwendung an dynamische Skalierung entspricht

  • Beurteilen Sie das Kosten-Nutzen-Verhältnis einer Reduzierung der Latenzzeit durch eine von Azure Service Bus abhängige Verteilung von PUSH-basierten Benachrichtigungen in Echtzeit.

Entwickler sollten Folgendes beachten:

  • Entwerfen Sie eine Messaginglösung, die die Batchverarbeitung beim Speichern und Abrufen von Daten aus Azure-Warteschlangen nutzt.

  • Bewerten Sie die automatische Skalierung in Azure, um festzustellen, ob sie den Anforderungen Ihrer Anwendung an dynamische Skalierung entspricht

  • Implementieren Sie einen effizienten Warteschlangenlistener-Dienst, um sicherzustellen, dass bei leeren Warteschlangen maximal ein Thread zum Entfernen von Elementen aus der Warteschlange für das Abrufen verwendet wird.

  • Skalieren Sie die Anzahl der Workerrolleninstanzen dynamisch abwärts, wenn Warteschlangen über einen längeren Zeitraum hinweg leer bleiben.

  • Implementieren Sie einen anwendungsspezifischen zufälligen exponentiellen Backoff-Algorithmus, um die Auswirkungen des Warteschlangenabrufs im Leerlauf auf die Speichertransaktionskosten zu reduzieren.

  • Setzen Sie die richtigen Techniken ein, die das Überschreiten von Skalierbarkeitszielen für eine einzelne Warteschlange verhindern, wenn Sie Warteschlangenverleger und -verbraucher mit vielen Threads und Instanzen implementieren.

  • Verwenden Sie eine stabile Wiederholungsrichtlinie, die eine Vielzahl von Übergangszuständen unterstützen kann, wenn Daten in Azure-Warteschlangen veröffentlicht bzw. genutzt werden.

  • Verwenden Sie die unidirektionale Ereignisfunktion, die von Azure Service Bus zur Unterstützung von PUSH-basierten Benachrichtigungen bereitgestellt wird, um die Latenzzeit zu reduzieren und die Leistung der warteschlangenbasierten Messaginglösung zu verbessern.

  • Untersuchen Sie die neuen Funktionen von .NET Framework 4, wie z. B. TPL, PLINQ und das Beobachter-Muster, um den Grad des Parallelismus zu maximieren, die Parallelität zu verbessern und den Entwurf von Multithreaddiensten zu vereinfachen.

Der zugehörige Beispielcode kann von der MSDN Code Gallery heruntergeladen werden. Der Beispielcode enthält auch alle erforderlichen Infrastrukturkomponenten, wie z. B. die Generika-bewusste Abstraktionsebene für den Azure-Warteschlangendienst, die in den oben aufgeführten Codeausschnitten nicht angegeben sind. Beachten Sie, dass alle Quellcodedateien der Microsoft Public License unterliegen, wie in den entsprechenden rechtlichen Hinweisen erläutert wird.

Anzeigen:
© 2014 Microsoft