Serverlose Ereignisverarbeitung

Cosmos DB
Functions
Monitor
Pipelines
Storage

Diese Referenzarchitektur zeigt eine serverlose, ereignisgesteuerte Architektur, die einen Datenstrom erfasst, die Daten verarbeitet und die Ergebnisse in eine Back-End-Datenbank schreibt.

Weitere Variationen und Lösungsideen im Zusammenhang mit dieser Referenzarchitektur sind im Abschnitt „Nächste Schritte“ dieses Artikels mit verknüpft.

Aufbau

Reference architecture for serverless event processing using Azure Functions

  • Ereignisse treffen auf Azure Event Hubs ein.
  • Eine Funktions-App wird ausgelöst, um das Ereignis zu bearbeiten.
  • Das Ereignis wird in einer Azure Cosmos DB-Datenbank gespeichert.
  • Wenn die Funktions-App das Ereignis nicht erfolgreich speichern kann, wird das Ereignis in einer Speicherwarteschlange für die spätere Verarbeitung gespeichert.

Komponenten

Der Datenstrom wird mit Event Hubs erfasst. Event Hubs ist für Datenstromszenarien mit hohem Durchsatz konzipiert.

Hinweis

Für Internet der Dinge (IoT)-Szenarien empfehlen wir Azure IoT Hub. IoT Hub verfügt über einen integrierten Endpunkt, der mit der Azure Event Hubs-API kompatibel ist, sodass Sie beide Dienste in dieser Architektur ohne größere Änderungen bei der Back-End-Verarbeitung nutzen können. Weitere Informationen finden Sie unter Verbinden von IoT-Geräten mit Azure: IoT Hub und Event Hubs.

Funktions-App. Azure Functions ist eine serverlose Computeoption. Es wird ein ereignisgesteuertes Modell verwendet, bei dem ein Codeabschnitt (eine Funktion) durch einen Trigger aufgerufen wird. Wenn in dieser Architektur Ergebnisse auf einer Event Hubs-Instanz eingehen, lösen sie eine Funktion aus, mit der die Ereignisse verarbeitet und die Ergebnisse in den Speicher geschrieben werden.

Funktions-Apps sind für die Verarbeitung einzelner Datensätze von Event Hubs geeignet. Für komplexere Szenarien zur Verarbeitung von Datenströmen können Sie erwägen, Apache Spark mit Azure Databricks oder Azure Stream Analytics zu verwenden.

Cosmos DB: Cosmos DB ist ein Datenbankdienst mit mehreren Modellen, der in einem serverlosen, verbrauchsbasierten Modus verfügbar ist. Für dieses Szenario speichert die Funktion für die Ereignisverarbeitung JSON-Datensätze mit der Cosmos DB-SQL-API.

Warteschlangenspeicher. Warteschlangenspeicher wird für unzustellbare Nachrichten verwendet. Wenn bei der Verarbeitung eines Ereignisses ein Fehler auftritt, speichert die Funktion die Ereignisdaten in einer Warteschlange für unzustellbare Nachrichten zur späteren Verarbeitung. Weitere Informationen finden Sie im Abschnitt „Resilienz“ weiter unten in diesem Artikel.

Azure Monitor: Monitor erfasst Leistungsmetriken zu den in der Lösung bereitgestellten Azure-Diensten. Durch die Visualisierung dieser Metriken in einem Dashboard können Sie einen Einblick in die Integrität der Lösung gewinnen.

Azure Pipelines. Pipelines ist ein CI-/CD-Dienst (Continuous Integration/Continuous Delivery), mit dem die Anwendung erstellt, getestet und bereitgestellt wird.

Überlegungen

Verfügbarkeit

Die hier dargestellte Bereitstellung befindet sich in nur einer Azure-Region. Nutzen Sie die Features für die geografische Verteilung in den verschiedenen Diensten, um einen stabileren Ansatz für die Notfallwiederherstellung zu erzielen:

  • Event Hubs. Erstellen Sie zwei Event Hubs-Namespaces: einen primären (aktiven) Namespace und einen sekundären (passiven) Namespace. Nachrichten werden automatisch an den aktiven Namespace weitergeleitet, sofern Sie kein Failover zum sekundären Namespace ausführen. Weitere Informationen finden Sie unter Georedundante Notfallwiederherstellung in Azure Event Hubs.
  • Funktions-App. Stellen Sie eine zweite Funktions-App bereit, die darauf wartet, vom sekundären Event Hubs-Namespace zu lesen. Mit dieser Funktion werden Daten in ein sekundäres Speicherkonto für die Warteschlange für unzustellbare Nachrichten geschrieben.
  • Cosmos DB. Cosmos DB unterstützt mehrere Schreibregionen, sodass Schreibvorgänge in alle Regionen möglich sind, die Sie Ihrem Cosmos DB-Konto hinzufügen. Wenn Sie die Funktion für mehrere Schreibvorgänge nicht aktivieren, können Sie trotzdem ein Failover auf die primäre Schreibregion ausführen. Die Cosmos DB-Client-SDKs und die Azure-Funktionsbindungen verarbeiten das Failover automatisch, sodass Sie keine Einstellungen für die Anwendungskonfiguration aktualisieren müssen.
  • „Azure Storage“. Verwenden Sie RA-GRS-Speicher für die Warteschlange für unzustellbare Nachrichten. Hierdurch wird ein schreibgeschütztes Replikat in einer anderen Region erstellt. Wenn die primäre Region ausfällt, können Sie die derzeit in der Warteschlange befindlichen Elemente lesen. Stellen Sie darüber hinaus ein weiteres Speicherkonto in der sekundären Region bereit, in das die Funktion nach einem Failover schreiben kann.

Skalierbarkeit

Event Hubs

Die Durchsatzkapazität von Event Hubs wird in Durchsatzeinheiten gemessen. Sie können einen Event Hub automatisch skalieren, indem Sie die Funktion für automatische Vergrößerung aktivieren. Dadurch werden die Durchsatzeinheiten basierend auf dem Datenverkehr automatisch bis zu einem konfigurierten Höchstwert hochskaliert.

Der Event Hub-Trigger in der Funktions-App wird gemäß der Anzahl von Partitionen im Event Hub skaliert. Jeder Partition wird jeweils eine Funktionsinstanz zugewiesen. Zur Erhöhung des Durchsatzes empfangen Sie die Ereignisse nicht einzeln nacheinander, sondern als Batch.

Cosmos DB

Cosmos DB ist in zwei verschiedenen Kapazitätsmodi verfügbar:

  • Serverlos, für Workloads mit zeitweiligem oder unvorhersehbarem Datenverkehr und einem geringen Verhältnis zwischen durchschnittlichem und hohem Datenverkehrsaufkommen.
  • Bereitgestellter Durchsatz für Workloads mit anhaltendem Datenverkehr, die vorhersagbare Leistung erfordern.

Um sicherzustellen, dass Ihre Workload skalierbar ist, ist es wichtig, beim Erstellen Ihres Cosmos DB-Containers einen geeigneten Partitionsschlüssel auszuwählen. Hier sind einige Merkmale eines gut geeigneten Partitionsschlüssels aufgeführt:

  • Der Schlüsselwertbereich ist ausreichend groß.
  • Es erfolgt eine gleichmäßige Verteilung von Lese- und Schreibvorgängen pro Schlüsselwert, um eine Überlastung von Schlüsseln zu vermeiden.
  • Die maximale Datenmenge, die für einen Schlüsselwert gespeichert wird, übersteigt niemals die maximale Größe der physischen Partition (20 GB).
  • Der Partitionsschlüssel für ein Dokument ändert sich nicht. Sie können den Partitionsschlüssel für ein vorhandenes Dokument nicht aktualisieren.

Im Szenario für diese Referenzarchitektur speichert die Funktion genau ein Dokument pro Gerät, das Daten sendet. Die Funktion aktualisiert die Dokumente laufend mit dem aktuellen Gerätestatus, indem ein Upsert-Vorgang verwendet wird. Die Geräte-ID ist ein guter Partitionsschlüssel für dieses Szenario, da Schreibvorgänge gleichmäßig auf die Schlüssel verteilt werden. Außerdem ist die Größe jeder Partition streng begrenzt, weil ein einzelnes Dokument für jeden Schlüsselwert vorhanden ist. Weitere Informationen zu Partitionsschlüsseln finden Sie unter Partitionieren und Skalieren in Azure Cosmos DB.

Resilienz

Beim Verwenden des Event Hubs-Triggers mit Functions ist es ratsam, Ausnahmen in Ihrer Verarbeitungsschleife abzufangen. Wenn ein Ausnahmefehler auftritt, führt die Functions-Runtime keinen Wiederholungsversuch für die Nachrichten durch. Wenn eine Nachricht nicht verarbeitet werden kann, sollte sie in eine Warteschlange für unzustellbare Nachrichten eingereiht werden. Verwenden Sie einen Out-of-band-Prozess, um die Nachrichten zu untersuchen und die Korrekturmaßnahmen zu bestimmen.

Mit dem folgenden Code wird veranschaulicht, wie die Erfassungsfunktion Ausnahmen abfängt und nicht verarbeitete Nachrichten in eine Warteschlange für unzustellbare Nachrichten einreiht.

[FunctionName("RawTelemetryFunction")]
[StorageAccount("DeadLetterStorage")]
public static async Task RunAsync(
    [EventHubTrigger("%EventHubName%", Connection = "EventHubConnection", ConsumerGroup ="%EventHubConsumerGroup%")]EventData[] messages,
    [Queue("deadletterqueue")] IAsyncCollector<DeadLetterMessage> deadLetterMessages,
    ILogger logger)
{
    foreach (var message in messages)
    {
        DeviceState deviceState = null;

        try
        {
            deviceState = telemetryProcessor.Deserialize(message.Body.Array, logger);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error deserializing message", message.SystemProperties.PartitionKey, message.SystemProperties.SequenceNumber);
            await deadLetterMessages.AddAsync(new DeadLetterMessage { Issue = ex.Message, EventData = message });
        }

        try
        {
            await stateChangeProcessor.UpdateState(deviceState, logger);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error updating status document", deviceState);
            await deadLetterMessages.AddAsync(new DeadLetterMessage { Issue = ex.Message, EventData = message, DeviceState = deviceState });
        }
    }
}

Beachten Sie, dass für die Funktion die Queue Storage-Ausgabebindung genutzt wird, um Elemente in die Warteschlange einzureihen.

Mit dem Code werden Ausnahmen auch in Application Insights protokolliert. Sie können den Partitionsschlüssel und die Sequenznummer auch verwenden, um unzustellbare Nachrichten mit den Ausnahmen in den Protokollen zu korrelieren.

Nachrichten in der Warteschlange für unzustellbare Nachrichten sollten über genügend Informationen verfügen, damit Sie den Kontext des Fehlers verstehen können. In diesem Beispiel enthält die Klasse DeadLetterMessage die Ausnahmenachricht, die ursprünglichen Ereignisdaten und die deserialisierte Ereignisnachricht (falls verfügbar).

public class DeadLetterMessage
{
    public string Issue { get; set; }
    public EventData EventData { get; set; }
    public DeviceState DeviceState { get; set; }
}

Nutzen Sie Azure Monitor, um den Event Hub zu überwachen. Wenn eine Eingabe vorhanden ist, aber keine Ausgabe, bedeutet dies, dass Nachrichten nicht verarbeitet werden. Navigieren Sie in diesem Fall zu Log Analytics, und suchen Sie nach Ausnahmen oder anderen Fehlern.

DevOps

Verwenden Sie nach Möglichkeit Infrastruktur als Code (Infrastructure as Code, IaC). Mit IaC werden die Infrastruktur, die Anwendung und Speicherressourcen mit einem deklarativen Ansatz wie z. B. Azure Resource Manager verwaltet. Dies hilft bei der Automatisierung der Bereitstellung mithilfe von DevOps als CI/CD-Lösung (Continuous Integration und Continuous Delivery). Vorlagen sollten eine Versionsangabe aufweisen und einen Teil der Releasepipeline darstellen.

Wenn Sie Vorlagen erstellen, gruppieren Sie Ressourcen, um sie pro Workload zu organisieren und zu isolieren. Eine gängige Methode der Berücksichtigung einer Workload ist eine einzelne serverlose Anwendung oder ein virtuelles Netzwerk. Die Workloadisolierung dient dazu, die Ressourcen einem Team zuzuordnen, damit das DevOps-Team alle Aspekte dieser Ressourcen unabhängig verwalten und CI/CD durchführen kann.

Diese Architektur umfasst Schritte zum Konfigurieren der Drone Status-Funktions-App unter Verwendung von Azure Pipelines mit YAML und Azure Functions-Slots.

Wenn Sie Ihre Dienste bereitstellen, müssen Sie sie überwachen. Sie können Application Insights verwenden, damit Entwickler die Leistung überwachen und Probleme erkennen können.

Weitere Informationen finden Sie im Microsoft Azure Well-Architected Framework unter Übersicht über die DevOps-Säule.

Notfallwiederherstellung

Die hier dargestellte Bereitstellung befindet sich in nur einer Azure-Region. Nutzen Sie die Features für die geografische Verteilung in den verschiedenen Diensten, um einen stabileren Ansatz für die Notfallwiederherstellung zu erzielen:

  • Event Hubs. Erstellen Sie zwei Event Hubs-Namespaces: einen primären (aktiven) Namespace und einen sekundären (passiven) Namespace. Nachrichten werden automatisch an den aktiven Namespace weitergeleitet, sofern Sie kein Failover zum sekundären Namespace ausführen. Weitere Informationen finden Sie unter Georedundante Notfallwiederherstellung in Azure Event Hubs.

  • Funktions-App. Stellen Sie eine zweite Funktions-App bereit, die darauf wartet, vom sekundären Event Hubs-Namespace zu lesen. Mit dieser Funktion werden Daten in ein sekundäres Speicherkonto für die Warteschlange für unzustellbare Nachrichten geschrieben.

  • Cosmos DB: Cosmos DB unterstützt mehrere Schreibregionen, sodass Schreibvorgänge in alle Regionen möglich sind, die Sie Ihrem Cosmos DB-Konto hinzufügen. Wenn Sie die Funktion für mehrere Schreibvorgänge nicht aktivieren, können Sie trotzdem ein Failover auf die primäre Schreibregion ausführen. Die Cosmos DB-Client-SDKs und die Azure-Funktionsbindungen verarbeiten das Failover automatisch, sodass Sie keine Einstellungen für die Anwendungskonfiguration aktualisieren müssen.

  • Azure Storage. Verwenden Sie RA-GRS-Speicher für die Warteschlange für unzustellbare Nachrichten. Hierdurch wird ein schreibgeschütztes Replikat in einer anderen Region erstellt. Wenn die primäre Region ausfällt, können Sie die derzeit in der Warteschlange befindlichen Elemente lesen. Stellen Sie darüber hinaus ein weiteres Speicherkonto in der sekundären Region bereit, in das die Funktion nach einem Failover schreiben kann.

Bereitstellen der Lösung

GitHub logo Eine Referenzimplementierung dieser Architektur ist auf GitHub verfügbar.

Preise

Verwenden Sie den Azure-Preisrechner, um die Kosten zu ermitteln. Siehe auch im Abschnitt Kosten des Microsoft Azure Well-Architected Frameworks. Hier finden Sie einige weitere Überlegungen dazu.

Azure-Funktionen

Azure Functions unterstützt zwei Hostingmodelle:

  • Verbrauchsplan. Computeleistung wird automatisch zugeordnet, wenn Ihr Code ausgeführt wird.
  • App Service-Plan. Für Ihren Code wird eine Gruppe mit virtuellen Computern (VMs) zugeordnet. Mit dem App Service-Plan wird die Anzahl von VMs und die VM-Größe definiert.

Bei dieser Architektur lösen alle Ereignisse, die auf Event Hubs eintreffen, eine Funktion aus, die das Ereignis verarbeitet. Aus Kostensicht lautet die Empfehlung, den Verbrauchstarif zu nutzen, da Sie hierbei nur für die verbrauchten Computeressourcen zahlen.

Azure Cosmos DB

Mit Cosmos DB zahlen Sie für die Vorgänge, die Sie mit der Datenbank ausführen, und für den von Ihren Daten genutzten Speicher.

  • Datenbankvorgänge. Die Art und Weise, wie Ihre Datenbankvorgänge abgerechnet werden, hängt vom Typ des Azure Cosmos DB-Kontos ab, das Sie verwenden.
    • Im serverlosen Modus müssen Sie beim Erstellen von Ressourcen in Ihrem Azure Cosmos-Konto keinen Durchsatz bereitstellen. Am Ende des Abrechnungszeitraums wird Ihnen die Anzahl der Anforderungseinheiten in Rechnung gestellt, die von den Datenbankvorgängen genutzt wurden.
    • Im Modus mit bereitgestelltem Durchsatz geben Sie den benötigten Durchsatz in Anforderungseinheiten pro Sekunde (RU/s) an, und Ihnen wird stündlich der maximal bereitgestellte Durchsatz für eine bestimmte Stunde abgerechnet. Hinweis: Da das Modell mit bereitgestelltem Durchsatz Ressourcen dediziert für Ihren Container oder Ihre Datenbank bereitstellt, wird Ihnen der Durchsatz, den Sie bereitgestellt haben, auch dann in Rechnung gestellt, wenn Sie keine Workloads ausführen.
  • Speicher Für die Gesamtmenge des Speichers (in GB), der für Daten und Indizes für eine angegebene Stunde genutzt wird, wird eine Pauschale berechnet.

Bei dieser Referenzarchitektur speichert die Funktion genau ein Dokument pro Gerät, das Daten sendet. Die Funktion aktualisiert die Dokumente fortlaufend mit dem aktuellen Gerätestatus, indem ein upsert-Vorgang verwendet wird. Dies ist in Bezug auf den verbrauchten Speicher kostengünstig. Weitere Informationen finden Sie unter Azure Cosmos DB – Preise.

Verwenden Sie den Cosmos DB Capacity Calculator, um eine schnelle Schätzung der Workloadkosten zu erhalten.

Nächste Schritte