Serverlose Ereignisverarbeitung mit Azure FunctionsServerless event processing using Azure Functions

Diese Referenzarchitektur zeigt eine serverlose, ereignisgesteuerte Architektur, die einen Datenstrom erfasst, die Daten verarbeitet und die Ergebnisse in eine Back-End-Datenbank schreibt.This reference architecture shows a serverless, event-driven architecture that ingests a stream of data, processes the data, and writes the results to a back-end database.

GitHub-Logo Eine Referenzimplementierung dieser Architektur ist auf GitHub verfügbar.GitHub logo A reference implementation for this architecture is available on GitHub.

Referenzarchitektur für die serverlose Ereignisverarbeitung mithilfe von Azure Functions

ArchitectureArchitecture

Der Datenstrom wird mit Event Hubs erfasst.Event Hubs ingests the data stream. Event Hubs ist für Datenstromszenarien mit hohem Durchsatz konzipiert.Event Hubs is designed for high-throughput data streaming scenarios.

Hinweis

Für IoT-Szenarien empfehlen wir die Verwendung von IoT Hub.For IoT scenarios, we recommend 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.IoT Hub has a built-in endpoint that’s compatible with the Azure Event Hubs API, so you can use either service in this architecture with no major changes in the backend processing. Weitere Informationen finden Sie unter Verbinden von IoT-Geräten mit Azure: IoT Hub und Event Hubs.For more information, see Connecting IoT Devices to Azure: IoT Hub and Event Hubs.

Funktions-App.Function App. Azure Functions ist eine serverlose Computeoption.Azure Functions is a serverless compute option. Es wird ein ereignisgesteuertes Modell verwendet, bei dem ein Codeabschnitt (eine „Funktion“) durch einen Trigger aufgerufen wird.It uses an event-driven model, where a piece of code (a “function”) is invoked by a trigger. 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.In this architecture, when events arrive at Event Hubs, they trigger a function that processes the events and writes the results to storage.

Funktions-Apps sind für die Verarbeitung einzelner Datensätze von Event Hubs geeignet.Function Apps are suitable for processing individual records from Event Hubs. 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.For more complex stream processing scenarios, consider Apache Spark using Azure Databricks, or Azure Stream Analytics.

Cosmos DB:Cosmos DB. Cosmos DB ist ein Datenbankdienst mit mehreren Modellen.Cosmos DB is a multi-model database service. Für dieses Szenario speichert die Funktion für die Ereignisverarbeitung JSON-Datensätze mit der Cosmos DB-SQL-API.For this scenario, the event-processing function stores JSON records, using the Cosmos DB SQL API.

Warteschlangenspeicher.Queue storage. Warteschlangenspeicher wird für unzustellbare Nachrichten verwendet.Queue storage is used for dead letter messages. 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.If an error occurs while processing an event, the function stores the event data in a dead letter queue for later processing. Weitere Informationen finden Sie unter Überlegungen zur Resilienz.For more information, see Resiliency Considerations.

Azure Monitor:Azure Monitor. Monitor erfasst Leistungsmetriken zu den in der Lösung bereitgestellten Azure-Diensten.Monitor collects performance metrics about the Azure services deployed in the solution. Durch die Visualisierung dieser Metriken in einem Dashboard können Sie einen Einblick in die Integrität der Lösung gewinnen.By visualizing these in a dashboard, you can get visibility into the health of the solution.

Azure Pipelines.Azure Pipelines. Pipelines ist ein CI-/CD-Dienst (Continuous Integration/Continuous Delivery), mit dem die Anwendung erstellt, getestet und bereitgestellt wird.Pipelines is a continuous integration (CI) and continuous delivery (CD) service that builds, tests, and deploys the application.

Überlegungen zur SkalierbarkeitScalability considerations

Event HubsEvent Hubs

Die Durchsatzkapazität von Event Hubs wird in Durchsatzeinheiten gemessen.The throughput capacity of Event Hubs is measured in throughput units. 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.You can autoscale an event hub by enabling auto-inflate, which automatically scales the throughput units based on traffic, up to a configured maximum.

Der Event Hub-Trigger in der Funktions-App wird gemäß der Anzahl von Partitionen im Event Hub skaliert.The Event Hub trigger in the function app scales according to the number of partitions in the event hub. Jeder Partition wird jeweils eine Funktionsinstanz zugewiesen.Each partition is assigned one function instance at a time. Zur Erhöhung des Durchsatzes empfangen Sie die Ereignisse nicht einzeln nacheinander, sondern als Batch.To maximize throughput, receive the events in a batch, instead of one at a time.

Cosmos DBCosmos DB

Die Durchsatzkapazität für Cosmos DB wird in Anforderungseinheiten (RU) gemessen.Throughput capacity for Cosmos DB is measured in Request Units (RU). Um einen Cosmos DB-Container auf eine Kapazität von mehr als 10.000 RU zu skalieren, müssen Sie beim Erstellen des Containers einen Partitionsschlüssel angeben und diesen in jedes von Ihnen erstellte Dokument einfügen.In order to scale a Cosmos DB container past 10,000 RU, you must specify a partition key when you create the container, and include the partition key in every document that you create.

Hier sind einige Merkmale eines gut geeigneten Partitionsschlüssels aufgeführt:Here are some characteristics of a good partition key:

  • Der Schlüsselwertbereich ist ausreichend groß.The key value space is large.
  • Es erfolgt eine gleichmäßige Verteilung von Lese- und Schreibvorgängen pro Schlüsselwert, um eine Überlastung von Schlüsseln zu vermeiden.There will be an even distribution of reads/writes per key value, avoiding hot keys.
  • Die maximale Datenmenge, die für einen Schlüsselwert gespeichert wird, übersteigt niemals die maximale Größe der physischen Partition (10 GB).The maximum data stored for any single key value will not exceed the maximum physical partition size (10 GB).
  • Der Partitionsschlüssel für ein Dokument ändert sich nicht.The partition key for a document won't change. Sie können den Partitionsschlüssel für ein vorhandenes Dokument nicht aktualisieren.You can't update the partition key on an existing document.

Im Szenario für diese Referenzarchitektur speichert die Funktion genau ein Dokument pro Gerät, das Daten sendet.In the scenario for this reference architecture, the function stores exactly one document per device that is sending data. Die Funktion aktualisiert die Dokumente laufend mit dem aktuellen Gerätestatus, indem ein Upsert-Vorgang verwendet wird.The function continually updates the documents with latest device status, using an upsert operation. 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.Device ID is a good partition key for this scenario, because writes will be evenly distributed across the keys, and the size of each partition will be strictly bounded, because there is a single document for each key value. Weitere Informationen zu Partitionsschlüsseln finden Sie unter Partitionieren und Skalieren in Azure Cosmos DB.For more information about partition keys, see Partition and scale in Azure Cosmos DB.

Überlegungen zur ResilienzResiliency considerations

Beim Verwenden des Event Hubs-Triggers mit Functions ist es ratsam, Ausnahmen in Ihrer Verarbeitungsschleife abzufangen.When using the Event Hubs trigger with Functions, catch exceptions within your processing loop. Wenn ein Ausnahmefehler auftritt, führt die Functions-Runtime keinen Wiederholungsversuch für die Nachrichten durch.If an unhandled exception occurs, the Functions runtime does not retry the messages. Wenn eine Nachricht nicht verarbeitet werden kann, sollte sie in eine Warteschlange für unzustellbare Nachrichten eingereiht werden.If a message cannot be processed, put the message into a dead letter queue. Verwenden Sie einen Out-of-band-Prozess, um die Nachrichten zu untersuchen und die Korrekturmaßnahmen zu bestimmen.Use an out-of-band process to examine the messages and determine corrective action.

Mit dem folgenden Code wird veranschaulicht, wie die Erfassungsfunktion Ausnahmen abfängt und nicht verarbeitete Nachrichten in eine Warteschlange für unzustellbare Nachrichten einreiht.The following code shows how the ingestion function catches exceptions and puts unprocessed messages onto a dead letter queue.

[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.Notice that the function uses the Queue storage output binding to put items in the queue.

Mit dem obigen Code werden Ausnahmen auch in Application Insights protokolliert.The code shown above also logs exceptions to Application Insights. Sie können den Partitionsschlüssel und die Sequenznummer auch verwenden, um unzustellbare Nachrichten mit den Ausnahmen in den Protokollen zu korrelieren.You can use the partition key and sequence number to correlate dead letter messages with the exceptions in the logs.

Nachrichten in der Warteschlange für unzustellbare Nachrichten sollten über genügend Informationen verfügen, damit Sie den Kontext des Fehlers verstehen können.Messages in the dead letter queue should have enough information so that you can understand the context of error. In diesem Beispiel enthält die Klasse DeadLetterMessage die Ausnahmenachricht, die ursprünglichen Ereignisdaten und die deserialisierte Ereignisnachricht (falls verfügbar).In this example, the DeadLetterMessage class contains the exception message, the original event data, and the deserialized event message (if available).

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.Use Azure Monitor to monitor the event hub. Wenn eine Eingabe vorhanden ist, aber keine Ausgabe, bedeutet dies, dass Nachrichten nicht verarbeitet werden.If you see there is input but no output, it means that messages are not being processed. Navigieren Sie in diesem Fall zu Log Analytics, und suchen Sie nach Ausnahmen oder anderen Fehlern.In that case, go into Log Analytics and look for exceptions or other errors.

Überlegungen zur NotfallwiederherstellungDisaster recovery considerations

Die hier dargestellte Bereitstellung befindet sich in nur einer Azure-Region.The deployment shown here resides in a single 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:For a more resilient approach to disaster-recovery, take advantage of geo-distribution features in the various services:

  • Event Hubs.Event Hubs. Erstellen Sie zwei Event Hubs-Namespaces: einen primären (aktiven) Namespace und einen sekundären (passiven) Namespace.Create two Event Hubs namespaces, a primary (active) namespace and a secondary (passive) namespace. Nachrichten werden automatisch an den aktiven Namespace weitergeleitet, sofern Sie kein Failover zum sekundären Namespace ausführen.Messages are automatically routed to the active namespace unless you fail over to the secondary namespace. Weitere Informationen finden Sie unter Georedundante Notfallwiederherstellung in Azure Event Hubs.For more information, see Azure Event Hubs Geo-disaster recovery.

  • Funktions-App.Function App. Stellen Sie eine zweite Funktions-App bereit, die darauf wartet, vom sekundären Event Hubs-Namespace zu lesen.Deploy a second function app that is waiting to read from the secondary Event Hubs namespace. Mit dieser Funktion werden Daten in ein sekundäres Speicherkonto für die Warteschlange für unzustellbare Nachrichten geschrieben.This function writes to a secondary storage account for dead letter queue.

  • Cosmos DB:Cosmos DB. Cosmos DB unterstützt mehrere Masterregionen, sodass Schreibvorgänge in alle Regionen möglich sind, die Sie Ihrem Cosmos DB-Konto hinzufügen.Cosmos DB supports multiple master regions, which enables writes to any region that you add to your Cosmos DB account. Wenn Sie die Funktion für mehrere Master (Multimaster) nicht aktivieren, können Sie trotzdem ein Failover in die primäre Schreibregion ausführen.If you don’t enable multi-master, you can still fail over the primary write region. Die Cosmos DB-Client-SDKs und die Azure-Funktionsbindungen verarbeiten das Failover automatisch, sodass Sie keine Einstellungen für die Anwendungskonfiguration aktualisieren müssen.The Cosmos DB client SDKs and the Azure Function bindings automatically handle the failover, so you don’t need to update any application configuration settings.

  • Azure Storage.Azure Storage. Verwenden Sie RA-GRS-Speicher für die Warteschlange für unzustellbare Nachrichten.Use RA-GRS storage for the dead letter queue. Hierdurch wird ein schreibgeschütztes Replikat in einer anderen Region erstellt.This creates a read-only replica in another region. Wenn die primäre Region ausfällt, können Sie die derzeit in der Warteschlange befindlichen Elemente lesen.If the primary region becomes unavailable, you can read the items currently in the queue. Stellen Sie darüber hinaus ein weiteres Speicherkonto in der sekundären Region bereit, in das die Funktion nach einem Failover schreiben kann.In addition, provision another storage account in the secondary region that the function can write to after a fail-over.

Bereitstellen der LösungDeploy the solution

Zeigen Sie zum Bereitstellen dieser Referenzarchitektur die GitHub-Infodatei an.To deploy this reference architecture, view the GitHub readme.

Nächste SchritteNext steps

Weitere Informationen zur Referenzimplementierung finden Sie unter Exemplarische Vorgehensweise mit Code: Serverlose Anwendung mit Azure Functions.To learn more about the reference implementation, read Code walkthrough: Serverless application with Azure Functions.