Bearbeiten

Freigeben über


Gridwich-Cloudmediensystem

Azure Blob Storage
Azure Event Grid
Azure-Funktionen
Azure Logic Apps

Die Gridwich-Pipelines erfassen, verarbeiten, speichern und veröffentlichen Medienobjekte mithilfe zweier neuer Methoden: die Azure Event Grid-Schichtstruktur und die Terraform-Schichtstruktur.

Aufbau

In der Gridwich-Architektur werden zwei Schichtstrukturen unterstützt, mit denen die Anforderungen asynchroner Ereignisverarbeitung und Infrastructure-as-Code erfüllt werden können:

  • Die Event Grid-Schichtstruktur abstrahiert Remoteprozesse und Prozesse mit langer Laufzeit wie die Mediencodierung weg vom externen Sagaworkflowsystem, indem diese zwischen zwei Event Grid-Handler geschichtet werden. Diese Schichtstruktur ermöglicht es dem externen System, ein Anforderungsereignis zu senden, geplante Ereignisse zu überwachen und auf eine schlussendliche Antwort über Erfolg oder Fehler zu warten, die innerhalb weniger Minuten oder auch erst Stunden später eintrifft.

    Abbildung der Schichtstruktur des Event Grid-Handlers

    Laden Sie eine Visio-Datei dieser Architektur herunter.

  • Die Terraform-Schichtstruktur ist ein mehrstufiges Terraform-Muster, das aktualisiert wird, um Infrastructure-as-Code unterstützen zu können. Durch die Trennung von Infrastrukturbereitstellung und Softwarerelease muss die Azure Functions-App veröffentlicht und ausgeführt werden, bevor Terraform das Event Grid-Abonnement bereitstellen kann. Zur Lösung dieser Anforderung gibt es zwei Terraform-Aufträge in der CI/CD-Pipeline:

    Abbildung der Aufträge mit Schichtstruktur von Terraform

    • Terraform 1 erstellt alle Ressourcen außer derjenigen für die Azure Event Grid-Abonnements.
    • Terraform 2 erstellt die Event Grid-Abonnements, sobald die Software ordnungsgemäß ausgeführt wird.

    So kann Terraform die Lösungsinfrastruktur insgesamt verwalten und bereitstellen, auch wenn nicht alle Azure-Ressourcen erstellt werden können, bevor die Softwareartefakte bereitgestellt werden.

Workflow

Der Gridwich-Prozess für Anforderung und Antwort deckt folgende Anforderungen ab:

  • Erstellung
  • Transport
  • Reception
  • Verteilung an Gridwich-Komponenten
  • Bestätigung und Aktionen
  • Antworten

Die folgenden Schritte beschreiben den Anforderungs- und Antwortprozess zwischen einem externen System und Gridwich. In Gridwich handelt es sich beim externen System um das Orchestrierungssystem für MAM und den Sagaworkflow. Die genauen Formate für Nachrichtenereignisse von Gridwich-Vorgängen finden Sie unter Gridwich-Formate für Anforderungs- und Antwortnachrichten.

Abbildung des Prozesses „Anforderung/Antwort“ in Gridwich

  1. Das externe System erstellt eine Anforderung und sendet sie an den Anforderungsbroker.

  2. In einem herkömmlichen Veröffentlichungs- und Abonnementmodell ist der Anforderungsbroker für die Verteilung der Anforderungen an Gridwich-Anforderungslistener verantwortlich. In dieser Lösung ist der Anforderungsbroker Azure Event Grid. Alle Anforderungen werden mithilfe des Event Grid-Ereignisschemas gekapselt.

  3. Die Azure Functions-App verarbeitet in Gridwich Ereignisse von Event Grid. Ein besserer Durchsatz wird erreicht, indem Gridwich einen HTTP-Endpunkt als Pushmodell definiert, das Event Grid initiiert, anstatt das Abrufmodell für Event Grid-Bindungen zu verwenden, das in Azure Functions zur Verfügung steht.

  4. Die Azure Functions-App liest die Ereigniseigenschaften und verteilt Ereignisse an Teile des Gridwich-Codes, die diesen Ereignistyp mit entsprechender Version verarbeiten.

  5. Jeder Handler, der mit der aktuellen Anforderung arbeitet, verwendet die allgemeine EventGridHandlerBase-Klasse, um eine Nachricht „Bestätigung“ zu senden, sobald die Anforderung empfangen wurde. Der Handler verteilt danach die Arbeit an die abgeleitete Klasse.

    Workflows für Gridwich-Anforderungen können synchron oder asynchron erfolgen. Bei Anforderungen, die einfach ausgeführt und schnell abgeschlossen werden können, übernimmt ein synchroner Handler die Arbeit und gibt ein Ereignis „Erfolg“ oder „Fehler“ zurück, sobald die Bestätigung gesendet wurde.

    Bei Anforderungen, die eine lange Laufzeit aufweisen, wertet ein asynchroner Handler die Anforderung aus, überprüft die Argumente und initiiert den Vorgang mit langer Laufzeit. Der Handler gibt dann eine Antwort „Geplant“ zurück, um zu bestätigen, dass die Arbeitsaktivität angefordert wurde. Sobald die Arbeitsaktivität abgeschlossen wurde, ist der Anforderungshandler dafür verantwortlich, für die Arbeit ein abgeschlossenes Ereignis „Erfolg“ oder „Fehler“ bereitzustellen.

    Der Dienst für die Ereignisveröffentlichung kommuniziert die Nachrichten „Bestätigung“, „Fehler“, „Geplant“ oder „Erfolg“ an den Event Grid-Anforderungsbroker.

  6. Der Ereignisherausgeber in der Azure-Funktion sendet das Antwortereignis an ein Event Grid-Thema, das als zuverlässiger Nachrichtenbroker fungiert. Das externe System abonniert das Thema und verarbeitet die Nachrichten. Die Event Grid-Plattform stellt die reguläre RETRY-Logik für die Veröffentlichung im externen System zur Verfügung.

Reihenfolge der Nachrichten

Während eine Bestätigung immer vor den Antworten „Erfolg“ und „Geplant“ erfolgt, kann Gridwich nicht gewährleisten, dass eine Antwort „Geplant“ immer vor einer entsprechenden Antwort „Erfolg“ erfolgt. Eine gültige Antwortreihenfolge kann entweder Bestätigt > Geplant > Erfolg oder Bestätigt > Erfolg > Geplant lauten.

Anforderungsfehler

Anforderungsfehler können entweder durch ungültige Anforderungen, nicht erfüllte Voraussetzungen, Verarbeitungsfehler, Sicherheitsausnahmen oder nicht verarbeitete Ausnahmen verursacht werden. Beinahe alle Fehler weisen die gleiche Nachrichtenform auf und beinhalten den ursprünglichen Wert für den Vorgangskontext. Die allgemeine EventGridHandlerBase-Klasse sendet in der Regel „Fehler“-Antworten über die Schnittstelle des Ereignisherausgebers der Azure-Funktion an Event Grid. Application Insights protokolliert Fehler außerdem über strukturierte Protokollierung.

Vorgangskontext

Das externe System kann Tausende an Anforderungen pro Tag, pro Stunde oder pro Sekunde erstellen. Jedes Anforderungsereignis für Gridwich muss eine JSON-Objekteigenschaft namens operationContext enthalten.

Wenn eine Anforderung einen Vorgangskontext enthält, z. B. {"id"="Op1001"}, muss jede {"id"="Op1001"} für Gridwich einen entsprechenden opaken Vorgangskontext enthalten, unabhängig davon, ob es sich um eine Anforderung mit kurzer oder langer Laufzeit handelt. Dieser Vorgangskontext gilt während der gesamten Lebensdauer, auch für Anforderungen mit langer Laufzeit.

Die Antwortanforderung gilt für ein „entsprechendes“ anstatt für dasselbe JSON-Objekt. Gridwich-Features wie die Kontextstummschaltung können von der Tatsache profitieren, dass das externe System das zurückgegebene JSON-Objekt von oben nach unten verarbeitet.

Genau genommen gilt für das externe System Folgendes:

  • Das System weist keine Abhängigkeit von der Reihenfolge der Eigenschaften auf, Gridwich kann also ein Objekt mit denselben Eigenschaften zurücksenden und dabei eine andere Reihenfolge verwenden. Beispiel: {"a":1,"b":2} vs. {"b":2,"a":1}.

  • Für das System entstehen keine Probleme bei zusätzlich vorhandenen Eigenschaften. Gridwich könnte nach Empfang von {"b":2,"a":1} also {"a":1,"b":2,"~somethingExtra":"yes"} gültig zurückgeben. Gridwich setzt als Präfix vor die Namen hinzugefügter Eigenschaften eine Tilde (~), um die Möglichkeit von Kollisionen zu minimieren. Beispiel: ~muted.

  • Das System weist keine Abhängigkeiten vom JSON-Format auf. Aus diesem Grund ist es beispielsweise nicht ersichtlich, ob eine Auffüllung mit Leerzeichen zur Zeichenfolgendarstellung eines JSON-Objekts gehört. Als Ausgleich dieser fehlenden Formatierungsabhängigkeit verwendet Gridwich Großschreibung, wobei unnötige Leerräume in der Zeichenfolgendarstellung von JSON-Objekten eliminiert werden. Weitere Informationen finden Sie unter JSONHelpers.SerializeOperationContext.

Sagateilnehmer und Vorgangskontext

Im Sagaorchestrierungssystem von Gridwich trägt jeder Sagateilnehmer mit mindestens einer Arbeitsaktivität zum System bei. Jeder Sagateilnehmer arbeitet unabhängig von den anderen Teilnehmern, und mehr als ein Sagateilnehmer kann für eine einzelne Anforderung tätig werden.

Jeder der Sagateilnehmer muss den Vorgangskontext beibehalten, kann ihn jedoch unterschiedlich implementieren. Beispiel:

  • Synchrone Vorgänge mit kurzer Laufzeit behalten den Vorgangskontext.
  • Azure Storage bietet eine opake Zeichenfolgeneigenschaft namens ClientRequestId für die meisten Vorgänge.
  • Einige Dienste verfügen über eine Eigenschaft Job.CorrelationData.
  • Andere Cloud-APIs bieten ähnliche Konzepte für einen opaken Vorgangskontext, der zurückgeben werden kann, wenn Fortschritt, Abschluss oder Fehler signalisiert werden.

Weitere Informationen zu Sagainstanzen und Sagateilnehmern finden Sie unter Sagaorchestrierung in Gridwich.

Synchrone und asynchrone Handler

Jeder Ereignishandler im System verwendet eine allgemeine EventGridHandlerBase-Klasse, um allgemeine Dienste wie die Anforderungsbestätigung, Fehlerverarbeitung und Veröffentlichung von Antwortereignissen bieten zu können. Der Dienst für die Ereignisveröffentlichung kommuniziert die Nachrichten „Bestätigung“, „Fehler“, „Geplant“ oder „Erfolg“ an den Event Grid-Anforderungsbroker.

Jeder Handler, der beabsichtigt, mit der aktuellen Anforderungen zu arbeiten, muss eine Bestätigung senden, wenn die Anforderung erhalten wurde. Die Basisklasse sendet sofort eine Nachricht „Bestätigung“ und verteilt die Arbeit dann an die abgeleitete Klasse.

Abbildung des Nachrichtenflusses für Bestätigungen

Synchrone Ereignisverarbeitung

Bei Anforderungen, die einfach ausgeführt und schnell abgeschlossen werden können, übernimmt der Handler die Arbeit synchron und gibt ein Ereignis „Erfolg“ zusammen mit dem dazugehörigen Vorgangskontext zurück, sobald die Bestätigung gesendet wurde.

Abbildung des synchronen Nachrichtenflusses für „Anforderung/Antwort“.

Bei ChangeBlobTierHandler handelt es sich beispielsweise um einen einfachen synchronen Flow. Der Handler ruft ein Anforderungs-DTO (Data Transfer Object, Datenübertragungsobjekt) ab, ruft einen einzelnen Dienst auf und wartet, dass dieser die Arbeit übernimmt. Dann gibt er eine Antwort „Erfolg“ oder „Fehler“ zurück.

Abbildung des ChangeBlobTierHandler-Beispiels für einen synchronen Flow

Asynchrone Ereignisverarbeitung

Einige Anforderungen weisen eine lange Laufzeit auf. Das Codieren von Mediendateien kann beispielsweise mehrere Stunden dauern. In diesen Fällen wertet ein asynchroner Handler die Anforderung aus, überprüft die Argumente und initiiert den Vorgang mit langer Laufzeit. Der Handler gibt dann eine Antwort „Geplant“ zurück, um zu bestätigen, dass die Arbeitsaktivität angefordert wurde.

Abbildung des asynchronen Nachrichtenflusses für „Anforderung/Antwort“.

Sobald die Arbeitsaktivität abgeschlossen wurde, ist der Anforderungshandler dafür verantwortlich, für die Arbeit ein abgeschlossenes Ereignis „Erfolg“ oder „Fehler“ bereitzustellen. Der Handler ist weiterhin zustandslos und muss den ursprünglichen Vorgangskontext abrufen und ihn in der Payload der Nachricht über Abschluss des Ereignisses platzieren.

BlobCopyHandler zeigt beispielsweise einen einfachen asynchronen Flow. Der Handler ruft ein Anforderungs-DTO ab, ruft einen einzelnen Dienst auf und wartet, dass dieser die Arbeit initiiert. Dann veröffentlicht er eine Antwort „Geplant“ oder „Fehler“.

Abbildung des BlobCopyHandler-Beispiels für einen asynchronen Flow mit Ereignis „Geplant“

Zum Abschluss des Anforderungsflows mit langer Laufzeit verwendet BlobCreatedHandler das Plattformereignis Microsoft.Storage.BlobCreated, extrahiert den ursprünglichen Vorgangskontext und veröffentlicht eine Abschlussantwort „Erfolg“ oder „Fehler“.

Abbildung des BlobCopyHandler-Beispiels für einen asynchronen Flow mit erfolgreichem Ereignis

Funktionen mit langer Ausführungszeit

Wenn Gridwich eine neue Funktions-App bereitstellt, werden aktuelle Prozesse mit langer Laufzeit möglicherweise angehalten. Wenn diese Prozesse abrupt beendet werden, gibt es keinen Status, und es erfolgt keine Meldung an die aufrufende Funktion. Gridwich muss eine neue Funktions-App bereitstellen und den Übergang für die Funktionen mit langer Laufzeit ordnungsgemäß verarbeiten und dabei keine Nachrichten auslassen.

Folgendes muss für die Lösung zutreffen:

  • Der Status der ausgeführten Instanzen der Gridwich-App darf nicht beibehalten werden.
  • Prozesse dürfen nicht beendet werden, nur weil eine neue Bereitstellung erfolgt oder eine neue Nachricht dieselbe Aktivität anfordert.
  • Es dürfen keine zusätzlichen Azure-Workloads wie Durable Functions, Funktions-Apps, Logic Apps oder Azure Container Instances aufgerufen werden.

Gridwich verwendet die Slotbereitstellung und Abbruchtoken von Azure Functions, um diese Anforderungen für zuverlässige Funktionen mit langer Laufzeit erfüllen zu können.

Die folgende Abbildung zeigt, wie die meisten Gridwich-Aufträge funktionieren. Das grüne Feld steht für einen Auftrag, der von Gridwich an einen externen Dienst übergeben wird. Gridwich reagiert dann auf ereignisgesteuerte Weise auf den Status. Das rote Feld zeigt eine Funktion, die für Gridwich selbst eine lange Laufzeit aufweist.

Abbildung von Funktionen mit kurzer und langer Laufzeit

Die Funktionsruntime fügt das Abbruchtoken hinzu, wenn die Anwendung heruntergefahren wird. Gridwich ermittelt das Token und gibt Fehlercodes für alle Anforderungen und aktuell ausgeführten Prozesse zurück.

Die Slotbereitstellung stellt neue Softwareversionen bereit. Der Produktionsslot verfügt über die ausgeführte Anwendung, der Stagingslot verfügt über die neue Version. Azure führt mehrere Bereitstellungsschritte durch und tauscht dann die Slotinstanzen. Als letzter Schritt des Prozesses wird die alte Instanz neu gestartet.

Gridwich wartet 30 Sekunden, nachdem die Hostnamen neu zugeordnet wurden. Für über HTTP ausgelöste Funktionen können von Gridwich also mindestens 30 Sekunden garantiert werden, bevor der Neustart des alten Produktionsslots durchgeführt wird. Andere Trigger werden möglicherweise von den App-Einstellungen gesteuert, die über keinen Mechanismus verfügen, der auf Aktualisierungen von App-Einstellungen wartet. Für diese Funktionen besteht das Risiko von Unterbrechungen, wenn die Ausführung startet, bevor der alte Produktionsslot neu gestartet wurde.

Weitere Informationen finden Sie unter Austauschvorgänge und Azure Functions-Bereitstellungsslots.

Komponenten

Die Gridwich-Medienverarbeitungslösung verwendet Azure Event Grid, Azure Functions, Azure Blob Storage, Azure Logic Apps und Azure Key Vault. Die CI/CD-Prozesse und die Sagaorchestrierungsprozesse verwenden Azure Repos, Azure Pipelines und Terraform.

  • Azure Event Grid verwaltet die Weiterleitung von Gridwich-Ereignissen. Dafür werden zwei geschichtete Event Grid-Aufträge verwendet, die eine asynchrone Medienereignisverarbeitung ermöglichen. Bei Event Grid handelt es sich um einen sehr zuverlässigen Endpunkt für die Anforderungsübermittlung. Die Azure-Plattform sorgt für die erforderliche Uptime und Stabilität des Endpunkts für die Anforderungsübermittlung.

    Gridwich kapselt Ereignisse im Event.Data-Eigenschaftenobjekt des Event Grid-Schemas, das opak für den Event Grid-Broker und die Transportschicht ist. Gridwich verwendet außerdem das eventType- und das dataVersion-Objektfeld, um Ereignisse weiterzuleiten. Damit der Event Grid-Anforderungsbroker also durch andere Broker für Ereignisse des Typs „Veröffentlichung/Abonnement“ ersetzt werden kann, sind für Gridwich möglichst wenige Ereignisfelder erforderlich. Die Felder topic oder subject werden nicht verwendet.

  • Azure Functions ermöglicht es Ihnen, ereignisgesteuerten Code auszuführen, ohne explizit eine Infrastruktur bereitstellen oder verwalten zu müssen. Gridwich ist eine Azure Functions-App, die die Ausführung verschiedener Funktionen hostet.

  • Azure Blob Storage bietet skalierbaren und kostengünstigen Cloudspeicher sowie Zugriff auf unstrukturierte Daten wie Medienobjekte. Gridwich verwendet sowohl Blockblobs als auch Container in Azure Storage.

  • Azure Key Vault schützt kryptografische Schüssel, Kennwörter und andere Geheimnisse, die Apps und Dienste von Azure und Drittanbietern nutzen.

  • Azure DevOps besteht aus mehren Diensten für Entwickler und Vorgänge, einschließlich Git-basierter Coderepositorys und automatisierter Build-und Releasepipelines, die mit Azure integriert werden können. Gridwich verwendet Azure Repos, um die Codeprojekte zu speichern und zu aktualisieren, sowie Azure Pipelines für CI/CD und andere Workflows.

  • Terraform ist ein Open-Source-Tool, das Infrastructure-as-Code verwendet, um Infrastrukturen und Dienste bereitzustellen und zu verwalten.

Alternativen

  • Durable Functions-Instanzen, die einen integrierten Zustandsspeicher für Vorgänge mit langer Laufzeit aufweisen, können auch einen opaken Vorgangskontext bereitstellen. Durable Functions-Instanzen könnten auch mehrere Aufgaben innerhalb eines Vorgangs erstellen und den Vorgangskontext als Eingabe oder Ausgabe für den Vorgang speichern. Tatsächlich könnte Gridwich Durable Functions für alle Arbeitsaktivitäten verwenden. Dieser Ansatz würde jedoch die Komplexität des Codes erhöhen.

  • Eine bessere Entkopplung von der Event Grid-Infrastruktur könnten Sie durch ein Refactoring von EventGridHandlerBase in RequestHandlerBase erzielen. Entfernen Sie dabei Bindungen mit Event Grid-Objekten oder -Typen. Diese umgestaltete Klasse könnte nur für Basis-DTOs verwendet werden, nicht für transportspezifische Objekttypen. Auf ähnliche Weise könnte IEventGridDispatcher zu IResponseDispatcher mit spezifischer EventGridDispatcher-Implementierung werden.

  • Die Gridwich.SagaParticipants.Storage.AzureStorage-Bibliothek enthält auch Speicherdienste, die andere Sagateilnehmer verwenden. Wenn Sie über die Schnittstellen in einem Kernprojekt verfügen, vermeidet dies IoC-Probleme (Inversion of Control), Sie könnten jedoch die Schnittstellen in eine eigenständige Gatewaybibliothek der Kernspeicherinfrastruktur extrahieren.

  • Die Funktions-App für Gridwich verwendet Abhängigkeitsinjektion, um einen oder mehrere Anforderungshandler für bestimmte Ereignistypen und Datenversionen zu registrieren. Die App injiziert EventGridDispatcher mit der Sammlung der Event Grid-Ereignishandler. Der Verteiler fragt die Handler ab, um zu bestimmen, welche das Ereignis verarbeiten werden.

    Alternativ könnten Sie den Mechanismus für Ereignisabonnement und Filterung verwenden, der von der Event Grid-Plattform bereitgestellt wird. Dieser Mechanismus stellt ein 1:1-Bereitstellungsmodell bereit, bei dem eine Azure-Funktion nur einen Ereignishandler hostet. Obwohl Gridwich ein 1:n-Modell verwendet, bedeutet die dazugehörige übersichtliche Architektur, dass ein Refactoring der Lösung in 1:1 nicht schwierig wäre.

  • Informationen zu einer alternativen Gridwich-Architektur, bei der Microservices anstelle von monolithischen Anwendungen verwendet werden, finden Sie unter Microservicealternative.

Szenariodetails

Ein bekanntes Massenmedien- und Unterhaltungskonglomerat hat seinen lokalen Videostreamingdienst durch eine cloudbasierte Lösung für das Erfassen, Verarbeiten und Veröffentlichen von Videoobjekten ersetzt. Die Hauptziele des Unternehmens bestanden darin, von der Kapazität, den Kosten und der Flexibilität der Azure-Cloud in den folgenden Bereichen zu profitieren:

  • Erfassen, Verarbeiten und Veröffentlichen von Videorohdateien sowie Verarbeiten von Medienanforderungen
  • Optimieren der Codierung und neuer Funktionen für Erfassung und Verteilung mit einem übersichtlich entworfenen Ansatz
  • Implementieren von Continuous Integration und Continuous Delivery (CI/CD) für die MAM-Pipeline (Media Asset Management, Verwaltung von Medienobjekten)

Zur Erfüllung dieser Ziele hat das Entwicklerteam von Microsoft Gridwich entwickelt, ein zustandsloses Framework für die Ereignisverarbeitung, das von einem externen Orchestrierungssystem für Sagaworkflows gesteuert wird.

Mögliche Anwendungsfälle

Das Entwicklerteam hat Gridwich entwickelt, um Prinzipien und Industriestandards in den folgenden Bereichen erfüllen zu können:

Das Gridwich-System umfasst Best Practices für die Verarbeitung und Veröffentlichung von Medienobjekten in Azure. Obwohl das Gridwich-System medienspezifisch ist, kann das Framework für Nachrichtenverarbeitung und Ereignisse auf jeden beliebigen zustandslosen Ereignisverarbeitungsworkflow angewendet werden.

Bereitstellen dieses Szenarios