Anmerkung
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel enthält Anleitungen zur Verbesserung der Leistung und Zuverlässigkeit Ihrer serverlosen Funktions-Apps . Eine allgemeinere Reihe bewährter Methoden für Azure-Funktionen finden Sie unter bewährte Methoden für Azure Functions.
Im Folgenden werden bewährte Methoden zum Erstellen und Entwerfen ihrer serverlosen Lösungen mithilfe von Azure Functions beschrieben.
Vermeiden Sie lang laufende Funktionen
Große, lang laufende Funktionen können zu unerwarteten Timeout-Problemen führen. Weitere Informationen zu Timeouts für einen bestimmten Hostingplan finden Sie unter Optimieren der Leistung und Zuverlässigkeit von Azure Functions.
Eine Funktion kann aufgrund vieler Node.js Abhängigkeiten groß werden. Das Importieren von Abhängigkeiten kann auch zu erhöhten Ladezeiten und unerwarteten Timeouts führen. Abhängigkeiten werden sowohl explizit als auch implizit geladen. Ein einzelnes Modul, das über Ihren Code geladen wird, kann eigene zusätzliche Module laden.
Gestalten Sie große Funktionen wann immer möglich in kleinere Funktionssätze um, die schnell zusammenarbeiten und Antworten zurückgeben. Eine Webhook- oder HTTP-Triggerfunktion kann z. B. eine Bestätigungsantwort innerhalb eines bestimmten Zeitlimits erfordern; Es ist üblich, dass Webhooks eine sofortige Antwort erfordern. Sie können die HTTP-Triggernutzlast an eine Warteschlange übergeben, die von einer Warteschlangentriggerfunktion verarbeitet werden soll. Mit diesem Ansatz können Sie die eigentliche Arbeit zurückstellen und eine sofortige Antwort zurückgeben.
Sicherstellen, dass Hintergrundaufgaben abgeschlossen sind
Wenn Ihre Funktion Aufgaben wie Rückrufe, Threads oder Prozesse startet, müssen diese abgeschlossen sein, bevor Ihr Funktionscode zurückgegeben wird. Da Functions diese Hintergrundthreads nicht nachverfolgt, können Standorte unabhängig vom Status des Hintergrundthreads heruntergefahren werden, was zu unbeabsichtigten Verhaltensweisen in Ihren Funktionen führen kann.
Wenn z. B. eine Funktion eine Hintergrundaufgabe startet und eine erfolgreiche Antwort zurückgibt, bevor die Aufgabe abgeschlossen wird, berücksichtigt die Funktionslaufzeit die Ausführung als erfolgreich abgeschlossen, unabhängig vom Ergebnis der Hintergrundaufgabe. Wenn diese Hintergrundaufgabe wichtige Arbeiten ausführt, kann sie durch das Herunterfahren des Standorts vorzeitig beendet werden, sodass diese Arbeiten in einem unbekannten Zustand bleiben.
Funktionsübergreifende Kommunikation
Dauerhafte Funktionen und Azure Logic Apps werden entwickelt, um Zustandsübergänge und die Kommunikation zwischen mehreren Funktionen zu verwalten.
Wenn weder Durable Functions noch Logic Apps zum Integrieren mit mehreren Funktionen verwendet werden, haben sich Speicherwarteschlangen für die funktionsübergreifende Kommunikation bewährt. Der Hauptgrund dafür ist, dass Speicherwarteschlangen billiger und viel einfacher bereitzustellen sind als andere Speicheroptionen.
Einzelne Nachrichten in einer Speicherwarteschlange sind auf 64 KB begrenzt. Wenn Sie größere Nachrichten zwischen Funktionen übergeben müssen, kann eine Azure Service Bus-Warteschlange verwendet werden, um Nachrichtengrößen bis zu 256 KB in der Standardebene und bis zu 100 MB in der Premium-Ebene zu unterstützen.
Service Bus-Themen sind nützlich, wenn Sie vor der Verarbeitung nachrichtenfiltern müssen.
Event Hubs sind nützlich, um die Kommunikation mit hohem Volumen zu unterstützen.
Funktionen schreiben, die zustandslos sind.
Funktionen sollten nach Möglichkeit zustandslos und idempotent sein. Ordnen Sie alle erforderlichen Statusinformationen Ihren Daten zu. Einer Bestellung, die verarbeitet wird, ist beispielsweise meist ein state-Member zugeordnet. Eine Funktion kann eine Reihenfolge basierend auf diesem Zustand verarbeiten, während die Funktion selbst zustandslos bleibt.
Idempotente Funktionen sind besonders bei Triggern mit Timer zu empfehlen. Wenn Sie beispielsweise etwas haben, das unbedingt einmal pro Tag ausgeführt werden muss, schreiben Sie es, damit es jederzeit während des Tages mit denselben Ergebnissen ausgeführt werden kann. Die Funktion kann beendet werden, wenn es für einen bestimmten Tag keine Arbeit gibt. Auch wenn eine vorherige Ausführung nicht abgeschlossen wurde, sollte die nächste Ausführung an der Stelle aufgenommen werden, an der sie unterbrochen wurde. Dies ist besonders wichtig für nachrichtenbasierte Bindungen, die bei einem Fehler erneut versuchen. Weitere Informationen finden Sie unter Entwerfen von Azure-Funktionen für identische Eingaben.
Defensive Funktionen schreiben
Angenommen, Ihre Funktion kann jederzeit eine Ausnahme haben. Entwerfen Sie Ihre Funktionen mit der Möglichkeit, während der nächsten Ausführung von einem vorherigen Fehlerpunkt fortzufahren. Betrachten Sie ein Szenario, das die folgenden Aktionen erfordert:
- Abfrage für 10.000 Zeilen in einer Datenbank.
- Erstellen Sie eine Warteschlangennachricht für jede Zeile, um die spätere Verarbeitung zu ermöglichen.
Je nachdem, wie komplex Ihr System ist, können Sie folgendes haben: Nachgeschaltete Dienste verhalten sich schlecht, Netzwerkausfälle oder Kontingentgrenzwerte erreicht usw. All diese Können ihre Funktion jederzeit beeinflussen. Sie müssen Ihre Funktionen so gestalten, dass sie darauf vorbereitet werden.
Wie reagiert Ihr Code, wenn nach dem Einfügen von 5.000 dieser Elemente in eine Warteschlange zur Verarbeitung ein Fehler auftritt? Verfolgen Sie Elemente in einem Set, das Sie abgeschlossen haben. Andernfalls können Sie sie beim nächsten Mal erneut einfügen. Diese Doppeleinfügung kann einen schwerwiegenden Einfluss auf Ihren Arbeitsablauf haben, also machen Sie Ihre Funktionen idempotent.
Wenn ein Warteschlangenelement bereits verarbeitet wurde, sollte es möglich sein, dass die Funktion eine No-Op-Funktion ist.
Nutzen Sie die bereits für Komponenten bereitgestellten Abwehrmaßnahmen, die Sie in der Azure Functions-Plattform verwenden. Informationen hierzu finden Sie beispielsweise in der Dokumentation zu Azure Storage-Warteschlangentriggern und -bindungen unter Behandeln von Nachrichten in der Warteschlange für nicht verarbeitbare Nachrichten.
Bei HTTP-basierten Funktionen sollten Sie API-Versionsverwaltungsstrategien mit Azure API Management in Betracht ziehen. Wenn Sie beispielsweise Ihre HTTP-basierte Funktions-App aktualisieren müssen, stellen Sie das neue Update in einer separaten Funktions-App bereit und verwenden API-Verwaltungsrevisionen oder -versionen, um Clients an die neue Version oder Revision zu leiten. Sobald alle Clients die Version oder Revision verwenden und keine weiteren Ausführungen in der vorherigen Funktions-App stattfinden, können Sie die vorherige Funktions-App deprovisionieren.
Bewährte Methoden der Funktionsorganisation
Im Rahmen Ihrer Lösung können Sie mehrere Funktionen entwickeln und veröffentlichen. Diese Funktionen werden häufig in einer einzelnen Funktions-App zusammengefasst, können aber auch in separaten Funktions-Apps ausgeführt werden. In Premium- und dedizierten Hostingplänen (App Service) können mehrere Funktions-Apps auch die gleichen Ressourcen gemeinsam nutzen, indem sie im selben Plan ausgeführt werden. Wie Sie Ihre Funktionen und Funktions-Apps gruppieren, hat Einfluss auf die Leistung, Skalierung, Konfiguration, Bereitstellung und Sicherheit Ihrer gesamten Lösung. Es gibt keine Regeln, die für jedes Szenario gelten. Berücksichtigen Sie daher die Informationen in diesem Abschnitt, wenn Sie Ihre Funktionen planen und entwickeln.
Organisieren von Funktionen für Leistung und Skalierung
Jede von Ihnen erstellte Funktion verfügt über einen Speicherbedarf. Auch wenn dieser Fußabdruck in der Regel klein ist, kann eine zu hohe Anzahl von Funktionen innerhalb einer Function-App dazu führen, dass Ihre App auf neuen Instanzen langsamer startet. Dies bedeutet auch, dass die Gesamtspeicherauslastung Ihrer Funktions-App möglicherweise höher ist. Es ist schwer zu sagen, wie viele Funktionen in einer einzelnen App sein sollen, was von Ihrer jeweiligen Arbeitsauslastung abhängt. Wenn Ihre Funktion jedoch viele Daten im Arbeitsspeicher speichert, sollten Sie in einer einzelnen App weniger Funktionen verwenden.
Wenn Sie mehrere Funktions-Apps in einem einzigen Premium-Plan oder einem dedizierten Plan (App Service) ausführen, teilen diese Apps alle die gleichen Ressourcen, die dem Plan zugeordnet sind. Wenn Sie über eine Funktions-App verfügen, die eine viel höhere Speicheranforderung als die anderen aufweist, wird für jede Instanz, für die die App bereitgestellt wird, eine unverhältnismäßige Menge an Arbeitsspeicherressourcen verwendet. Da dadurch weniger Arbeitsspeicher für die anderen Apps in jeder Instanz verfügbar sein könnte, sollten Sie eine Funktions-App mit hohem Arbeitsspeicher wie diesem in ihrem eigenen separaten Hostingplan ausführen.
Hinweis
Bei Verwendung des Verbrauchsplans empfehlen wir Ihnen, jede App immer in einen eigenen Plan zu setzen, da Apps trotzdem unabhängig skaliert werden. Weitere Informationen finden Sie unter "Mehrere Apps" im selben Plan.
Überlegen Sie, ob Sie Funktionen mit unterschiedlichen Ladeprofilen gruppieren möchten. Wenn Sie beispielsweise über eine Funktion verfügen, die viele Tausende von Warteschlangennachrichten verarbeitet, und eine andere, die nur gelegentlich aufgerufen wird, aber hohe Speicheranforderungen aufweist, sollten Sie sie in separaten Funktions-Apps bereitstellen, damit sie ihre eigenen Ressourcengruppen erhalten und unabhängig voneinander skaliert werden.
Organisieren von Funktionen für Konfiguration und Bereitstellung
Funktions-Apps verfügen über eine host.json Datei, die zum Konfigurieren des erweiterten Verhaltens von Funktionstriggern und der Azure Functions-Laufzeit verwendet wird. Änderungen an der host.json Datei gelten für alle Funktionen innerhalb der App. Wenn Sie über einige Funktionen verfügen, die benutzerdefinierte Konfigurationen benötigen, sollten Sie sie in ihre eigene Funktions-App verschieben.
Alle Funktionen in Ihrem lokalen Projekt werden zusammen als Eine Reihe von Dateien für Ihre Funktions-App in Azure bereitgestellt. Möglicherweise müssen Sie einzelne Funktionen separat bereitstellen oder Features wie Bereitstellungsplätze für einige Funktionen und nicht für andere verwenden. In solchen Fällen sollten Sie diese Funktionen (in separaten Codeprojekten) für verschiedene Funktions-Apps bereitstellen.
Organisieren von Funktionen nach Berechtigungen
Verbindungszeichenfolgen und andere in den Anwendungseinstellungen gespeicherte Anmeldeinformationen geben allen Funktionen in der Funktions-App den gleichen Satz von Berechtigungen in der zugehörigen Ressource. Erwägen Sie, die Anzahl der Funktionen mit Zugriff auf bestimmte Anmeldeinformationen zu minimieren, indem Sie Funktionen, die diese Anmeldeinformationen nicht nutzen, in eine separate Funktions-App verlagern. Sie können stets Techniken wie Funktionsverkettung nutzen, um Daten in verschiedenen Funktions-Apps zwischen Funktionen zu übergeben.
Bewährte Methoden für Skalierbarkeit
Es gibt eine Reihe von Faktoren, die sich darauf auswirken, wie Instanzen Ihrer Funktions-App skaliert werden. Die Details werden in der Dokumentation zur Funktionsskalierung bereitgestellt. Im Folgenden sind einige bewährte Methoden aufgeführt, um eine optimale Skalierbarkeit einer Funktions-App zu gewährleisten.
Freigeben und Verwalten von Verbindungen
Wiederverwenden von Verbindungen zu externen Ressourcen, wenn möglich. Erfahren Sie , wie Verbindungen in Azure Functions verwaltet werden.
Vermeiden der Freigabe von Speicherkonten
Wenn Sie eine Funktions-App erstellen, müssen Sie sie einem Speicherkonto zuordnen. Die Speicherkontoverbindung wird in der AzureWebJobsStorage-Anwendungseinstellung verwaltet.
Verwenden Sie für jede Funktions-App ein separates Speicherkonto, um die Leistung zu maximieren. Dieser Ansatz ist besonders wichtig, wenn Sie über dauerhafte Funktionen oder Event Hubs ausgelöste Funktionen verfügen, die beide ein hohes Volumen von Speichertransaktionen generieren. Wenn Ihre Anwendungslogik mit Azure Storage interagiert (direkt mit dem Storage SDK oder über eine der Speicherbindungen), sollten Sie ein dediziertes Speicherkonto verwenden. Wenn Sie z. B. über eine Ereignishub-ausgelöste Funktion verfügen, die Daten in den Blob-Speicher schreibt, verwenden Sie zwei Speicherkonten: eines für die Funktions-App und ein weiteres für die Blobs, die die Funktion speichert.
Vermeiden Sie es, Test- und Produktionscodes in der derselben Funktionen-App zu mischen.
Funktionen in einer Funktions-App teilen Ressourcen. Der Arbeitsspeicher wird beispielsweise freigegeben. Wenn Sie eine Funktions-App in der Produktion verwenden, fügen Sie keine testbezogenen Funktionen und Ressourcen hinzu. Es kann zu unerwartetem Aufwand bei der Ausführung von Produktionscode führen.
Achten Sie darauf, was Sie in Ihren Produktionsfunktions-Apps laden. Der Speicher wird über jede Funktion in der App hinweg gemittelt.
Wenn Sie eine gemeinsame Assembly nutzen, auf die in mehreren .NET-Funktionen verwiesen wird, sollten Sie sie in einem freigegebenen Ordner einfügen. Andernfalls könnten Sie versehentlich mehrere Versionen derselben Binärdatei bereitstellen, die sich zwischen Funktionen unterschiedlich verhalten.
Verwenden Sie keine ausführliche Protokollierung im Produktionscode, was sich negativ auf die Leistung auswirkt.
Verwenden von asynchronem Code bei Vermeidung von blockierenden Aufrufen
Die asynchrone Programmierung ist eine empfohlene bewährte Methode, insbesondere beim Blockieren von E/A-Vorgängen.
Vermeiden Sie in C# immer das Verweisen auf die Result-Eigenschaft oder das Aufrufen der Wait-Methode bei einer Task-Instanz. Dieser Ansatz kann zur Threadauslastung führen.
Tipp
Wenn Sie die HTTP- oder WebHook-Bindungen verwenden möchten, vermeiden Sie die Portauslastung, die durch nicht ordnungsgemäße Instanziierung von HttpClient verursacht werden kann. Weitere Informationen finden Sie unter How to manage connections in Azure Functions (Verwalten von Verbindungen in Azure Functions).
Verwenden mehrerer Workerprozesse
Standardmäßig verwendet jede Hostinstanz für Funktionen einen einzelnen Arbeitsprozess. Um die Leistung zu verbessern, insbesondere bei Singlethread-Runtimes wie Python, verwenden Sie die FUNCTIONS_WORKER_PROCESS_COUNT , um die Anzahl der Arbeitsprozesse pro Host (bis zu 10) zu erhöhen. Azure Functions versucht dann, gleichzeitige Funktionsaufrufe gleichmäßig auf diese Worker zu verteilen.
Die FUNCTIONS_WORKER_PROCESS_COUNT gilt für jeden Host, der von Functions erstellt wird, wenn Ihre Anwendung horizontal skaliert wird, um die Anforderungen zu erfüllen.
Empfangen von Nachrichten in Batches (sofern möglich)
Einige Trigger wie Event Hub ermöglichen das Empfangen eines Batches von Nachrichten in einem einzigen Aufruf. Das Batching von Nachrichten hat eine wesentlich bessere Leistung. Sie können die maximale Batchgröße in der host.json Datei so konfigurieren, wie in der host.json Referenzdokumentation beschrieben.
Bei C#-Funktionen können Sie den Typ in ein stark typisiertes Array ändern. Anstelle der EventData sensorEvent könnte die Methodensignatur z. B. EventData[] sensorEvent sein. Für andere Sprachen müssen Sie die Kardinalitätseigenschaft explizit in Ihrer function.json auf many festlegen, um die Batchverarbeitung wie hier gezeigt zu aktivieren.
Konfigurieren des Host-Verhaltens zum besseren Verwalten der Parallelität
Die host.json Datei in der Funktions-App ermöglicht die Konfiguration von Hostlaufzeit und Triggerverhalten. Zusätzlich zu Batchverhalten können Sie die Parallelität für eine Reihe von Triggern verwalten. Eine häufige Anpassung der Werte in diesen Optionen kann die Skalierung der Instanz an die Anforderungen der aufgerufenen Funktionen vereinfachen.
Einstellungen in der host.json Datei gelten für alle Funktionen innerhalb der App innerhalb einer einzigen Instanz der Funktion. Wenn Sie beispielsweise eine Funktions-App mit zwei HTTP-Funktionen und maxConcurrentRequests Anforderungen auf 25 festgelegt haben, zählt eine Anforderung an einen der beiden HTTP-Trigger zu den freigegebenen 25 gleichzeitigen Anforderungen. Wenn diese Funktions-App auf 10 Instanzen skaliert wird, ermöglichen die zehn Funktionen effektiv 250 gleichzeitige Anforderungen (10 Instanzen * 25 gleichzeitige Anforderungen pro Instanz).
Weitere Hostkonfigurationsoptionen finden Sie im host.json Konfigurationsartikel.
Nächste Schritte
Weitere Informationen finden Sie in den folgenden Ressourcen: