Hinweis
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.
Die Durable Functions-Laufzeit speichert automatisch Funktionsparameter, Rückgabewerte und andere Zustände im Task Hub, um eine zuverlässige Ausführung zu gewährleisten. Umfang und Häufigkeit der im dauerhaftem Speicher aufbewahrten Daten können sich jedoch auf die Leistung der Anwendung und die Kosten für Speichertransaktion auswirken. Abhängig von dem Datentyp, der von Ihrer Anwendung gespeichert wird, müssen auch die Richtlinien für die Datenaufbewahrung und den Datenschutz berücksichtigt werden.
In diesem Artikel wird erläutert, welche Daten beibehalten werden, wie sie große Nutzlasten und vertrauliche Daten behandeln und wie Sie die Serialisierung für jede unterstützte Sprache anpassen.
In diesem Artikel:
- Inhalt des Aufgabenhubs – Welche Daten gespeichert werden und wie
- Halten Sie Eingaben und Ausgaben klein – Strategien zum Verwalten der Nutzlastgröße
- Arbeiten mit vertraulichen Daten – Schützen von geheimnissen und persönlich identifizierbaren Informationen
- Sichern Des Task Hub-Speichers – Schützen Des Speicher-Back-End vor unbefugtem Zugriff
- Anpassen der Serialisierung und Deserialisierung – Sprachspezifische Serialisierungsoptionen
Inhalt des Aufgabenhubs
Aufgabenhubs speichern den aktuellen Status von Instanzen und alle ausstehenden Nachrichten:
- Instanzzustände speichern den aktuellen Status und den Verlauf einer Instanz. Für Orchestrierungsinstanzen umfasst dieser Status den Runtimezustand, den Orchestrierungsverlauf, Eingaben, Ausgaben und den benutzerdefinierten Status. Für Entitätsinstanzen enthält sie den Entitätsstatus.
- Nachrichten speichern Funktionseingaben oder -ausgaben, Ereignisnutzdaten und Metadaten, die für interne Zwecke verwendet werden, z. B. für Routing und End-to-End-Korrelation.
Nachrichten werden nach der Verarbeitung gelöscht, aber Instanzenzustände bleiben erhalten, es sei denn, sie werden explizit von der Anwendung oder einem Operator gelöscht. Insbesondere verbleibt eine Orchestrierungsgeschichte auch nach Abschluss der Orchestrierung im Speicher.
Ein Beispiel dafür, wie Zustände und Nachrichten den Fortschritt einer Orchestrierung darstellen, finden Sie im Ausführungsbeispiel des Aufgabenhubs.
Wo und wie Zustände und Nachrichten im Speicher dargestellt werden, hängt vom Speicheranbieter ab. Der Durable Functions-Standardanbieter ist Azure Storage, der Daten in Warteschlangen, Tabellen und Blobs in einem von Ihnen angegebenen Azure Storage-Konto speichert.
Datentypen, die serialisiert und beibehalten werden
In der folgenden Liste sind die verschiedenen Datentypen aufgeführt, die serialisiert und beibehalten werden, wenn Features von Durable Functions verwendet werden:
- Alle Ein- und Ausgaben von Orchestrator-, Aktivitäts- und Entitätsfunktionen, einschließlich aller IDs und nicht behandelten Ausnahmen
- Namen der Orchestrator-, Aktivitäts- und Entitätsfunktionen
- Namen und Nutzdaten externer Ereignisse
- Statusnutzdaten der benutzerdefinierten Orchestrierung
- Nachrichten zur Beendigung der Orchestrierung
- Dauerhafte Timernutzdaten
- Dauerhafte HTTP-Anforderungen und Antwort-URLs, Header und Nutzdaten
- Nutzdaten zu Entitätsaufrufen und Signalen
- Nutzdaten zum Entitätszustand
Anleitungen zum Verwalten der Nutzlastgröße und zum Schützen vertraulicher Elemente in dieser Liste finden Sie in den folgenden Abschnitten.
Halten Sie Durable Functions Eingaben und Ausgaben klein
Wenn Sie umfangreiche Eingaben und Ausgaben für und von Durable Functions-APIs bereitstellen, können Speicherprobleme auftreten. Eingaben und Ausgaben werden in die Orchestrierungshistorie serialisiert, was bedeutet, dass große Nutzlasten im Laufe der Zeit erheblich zu einem unkontrollierten Wachstum der Historie beitragen können. Dieses Wachstum birgt das Risiko, während der Wiedergabe Speicherfehler zu verursachen.
Um die Auswirkungen großer Eingaben und Ausgaben zu verringern, können Sie:
- Delegieren Sie Aufgaben an Unter-Orchestratoren, um die Speicherbelastung des Verlaufs über mehrere Orchestratoren hinweg auszugleichen, sodass der Speicherbedarf einzelner Verlaufsgeschichten gering bleibt.
- Speichern Sie große Daten im externen Speicher (z. B. Azure Blob Storage), und übergeben Sie einfache Bezeichner, mit denen Sie diese Daten bei Bedarf innerhalb von Aktivitätsfunktionen abrufen können.
Wenn Sie "Durable Task Scheduler" verwenden, können Sie auch große Nutzlastunterstützung verwenden, um größere Nutzlasten in Azure Blob Storage zu entladen.
Tip
Die bewährte Methode für den Umgang mit großen Daten besteht darin, sie bei Bedarf im externen Speicher zu halten und diese Daten nur innerhalb von Aktivitäten zu materialisieren.
Arbeiten mit vertraulichen Daten
Eingaben und Ausgaben (einschließlich Ausnahmen) an und von Durable Functions-APIs werden in Ihrem Storageanbieter der Wahl dauerhaft beibehalten. Wenn diese Eingaben, Ausgaben oder Ausnahmen vertrauliche Daten enthalten (z. B. geheime Daten, Verbindungszeichenfolgen oder persönlich identifizierbare Informationen), kann jeder Benutzer mit Lesezugriff auf die Ressourcen Ihres Speicheranbieters diese abrufen.
Um vertrauliche Daten sicher zu verarbeiten, rufen Sie diese Daten innerhalb von Aktivitätsfunktionen aus Azure Key Vault oder Umgebungsvariablen ab, und kommunizieren Sie diese Daten niemals direkt an Orchestratoren oder Entitäten. Dieser Ansatz verhindert, dass vertrauliche Daten in Ihre Speicherressourcen fließen.
Ebenso muss der Schreibzugriff auf Speicherressourcen eng kontrolliert werden, da manipulierte Daten im Speicher das Orchestrierungsverhalten ändern könnten. Weitere Informationen zum Sichern des Aufgabenhubspeichers finden Sie unter Sichern des Task Hub-Speichers.
Tip
Diese Anleitung gilt auch für die CallHttp Orchestrator-API, die ihre Anforderungs- und Antwortnutzlasten im Speicher speichert. Wenn für Ihre Ziel-HTTP-Endpunkte eine Authentifizierung erforderlich ist, implementieren Sie den HTTP-Aufruf innerhalb einer Aktivität, oder verwenden Sie die integrierte Unterstützung für verwaltete Identitäten, die von CallHttp angeboten wird, wodurch Anmeldeinformationen nicht im Speicher abgelegt werden.
Note
Vermeiden Sie das Protokollieren von Daten, die geheime Schlüssel enthalten, da jeder mit Lesezugriff auf Ihre Protokolle (z. B. in Application Insights) diese geheimen Schlüssel abrufen kann.
Verschlüsselung im Ruhezustand
Bei Verwendung des Azure Storage-Dienstes werden alle Daten im Ruhezustand automatisch verschlüsselt. Jeder Benutzer, der Zugriff auf das Speicherkonto hat, kann die Daten jedoch in unverschlüsselter Form lesen. Wenn Sie vertrauliche Daten stärker schützen möchten, sollten Sie in Erwägung ziehen, die Daten zunächst mit Ihren eigenen Verschlüsselungsschlüsseln zu verschlüsseln, damit die Daten in einer vorverschlüsselten Form gespeichert werden.
Alternativ können .NET-Benutzer benutzerdefinierte Serialisierungsanbieter implementieren, die eine automatische Verschlüsselung bereitstellen. Ein Beispiel für die benutzerdefinierte Serialisierung mit Verschlüsselung finden Sie in diesem GitHub-Beispiel.
Note
Wenn Sie sich für die Implementierung der Verschlüsselung auf Anwendungsebene entscheiden, beachten Sie, dass Orchestrierungen und Entitäten für eine unbegrenzte Zeit vorhanden sein können. Dies ist wichtig, wenn Sie Ihre Verschlüsselungsschlüssel rotieren müssen, da eine Orchestrierung oder Entitäten länger ausgeführt werden können, als Ihre Richtlinie für die Schlüsselrotation gilt. Bei einer Schlüsselrotation ist der Schlüssel zum Verschlüsseln der Daten möglicherweise nicht mehr für die Entschlüsselung verfügbar, wenn die Orchestrierung oder Entität das nächste Mal ausgeführt wird. Benutzerdefinierte Verschlüsselung wird daher nur empfohlen, wenn Orchestrierungen und Entitäten für relativ kurze Zeiträume laufen sollen.
Sichern Sie den Speicher Ihres Task Hub
Das Speicher-Back-End, das Ihren Aufgabenhub hostt, ist eine wichtige Vertrauensgrenze. Das Durable Task Framework vertraut den Daten, die es während der Wiederholung der Orchestrierung und der Nachrichtenverarbeitung aus dem Speicher liest. Jeder Benutzer, der Schreibzugriff auf den Aufgabenhubspeicher hat, kann den Orchestrierungsstatus, ausstehende Nachrichten oder gespeicherte Nutzlasten manipulieren. Dies kann das Anwendungsverhalten ändern, unbeabsichtigte Aktionen auslösen oder Remotecodeausführung im Kontext Ihrer Funktions-App erzielen.
Important
Geben Sie die Speicheranmeldeinformationen des Aufgabenhubs nicht preis, und gewähren Sie nicht vertrauenswürdigen Dritten keinen Schreibzugriff. Der Schreibzugriff auf den Task Hub-Speicher kann verwendet werden, um das Anwendungsverhalten zu ändern, einschließlich des Auslösens beliebiger Codeausführung.
Gemeinsame Verantwortung
Das Sichern des Speicher-Back-Ends liegt in Ihrer Verantwortung, genauso wie das Sichern einer Datenbank, die den Anwendungsstatus oder Code speichert. Das permanente Aufgabenframework führt keine Integritätsüberprüfung für gespeicherte Daten durch, sodass es von den Zugriffssteuerelementen der Speicherschicht abhängt, um nicht autorisierte Änderungen zu verhindern.
Wenn Sie den Durable Task Scheduler verwenden, wird das Speicher-Back-End vollständig verwaltet und durch den Dienst gesichert, wobei die verwaltete Identitätsauthentifizierung und die rollenbasierte Zugriffssteuerung (RBAC) verwendet wird. Für bring-your-own (BYO)-Speicher-Back-Ends wie Azure Storage, MSSQL oder Netherite müssen Sie die zugrunde liegenden Speicherressourcen selbst sichern.
Note
Verwenden Sie nicht denselben Task Hub für nicht vertrauenswürdige Mandanten gemeinsam. Ein Aufgabenhub setzt keine Zugriffsgrenzen zwischen seinen Nutzern durch, sodass jeder Mandant, der den Aufgabenhub lesen oder in ihn schreiben kann, alle darin enthaltenen Orchestrierungen und Entitäten beeinflussen kann. Ebenso sollten Sie sich nicht auf separate Aufgabenhubs innerhalb desselben Backends als Sicherheitsgrenze verlassen. Während der permanente AufgabenplanerRBAC unterstützt, der auf einzelne Aufgabenhubs festgelegt ist, gelten Netzwerksteuerelemente wie IP-Zulassungslisten und private Endpunkte nur auf Planerebene, sodass Aufgabenhubs innerhalb eines Schedulers keine Sicherheitsisolationsgrenze darstellen. Das gleiche gilt für BYO-Speicheranbieter– jeder Mandant mit Zugriff auf das Speicherkonto oder die Datenbank kann alle Aufgabenhubs auf diesem Back-End erreichen. Wenn Sie eine Sicherheitsisolation zwischen Mandanten benötigen, stellen Sie separate Infrastruktur für jeden Mandanten bereit: separate Speicherkonten oder Datenbanken für BYO-Anbieter oder separate Dauerhafte Taskplanerinstanzen.
Prüfliste für die Speicherhärtung
Wenden Sie die folgenden bewährten Methoden zum Schutz Ihres Task Hub-Speichers an:
- Verwenden Sie identitätsbasierte Verbindungen anstelle von Verbindungszeichenfolgen mit Speicherschlüsseln. Verwaltete Identitäten bieten eine differenzierte Zugriffssteuerung und beseitigen das Risiko von Verlusten an Anmeldeinformationen. Siehe Konfigurieren einer verwalteten Identität für Durable Functions.
- Wenden Sie RBAC-Rollen mit geringsten Berechtigungen an. Erteilen Sie nur die erforderlichen Mindestberechtigungen. Vermeiden Sie die Gewährung eines umfassenden Speicherkontozugriffs auf Benutzer oder Dienste, die es nicht benötigen.
- Beschränken Sie den Netzwerkzugriff auf Ihr Speicherkonto mithilfe privater Endpunkte oder Dienstendpunkte. Dadurch wird der nicht autorisierte Zugriff auf Netzwerkebene auf Aufgabenhubdaten verhindert.
-
Überwachen Sie den Speicherzugriff, indem Sie Azure Monitor-Ressourcenprotokolle für Ihr Speicherkonto aktivieren, insbesondere die Protokollkategorie
StorageWrite. Leiten Sie diese Protokolle an ein Ziel außerhalb des überwachten Speicherkontos weiter, z. B. Log Analytics, sodass sie nicht manipuliert werden können. Siehe Speicherprotokolle. - Wechseln Sie Anmeldeinformationen regelmäßig, wenn Sie Verbindungszeichenfolgen verwenden. Behandeln Sie Speicherkontoschlüssel mit der gleichen Sorgfalt wie alle anderen Anmeldeinformationen mit hohen Berechtigungen.
- Betrachten Sie ein verwaltetes Speicher-Back-End. Der Permanente Aufgabenplaner behandelt die Speichersicherheit automatisch, einschließlich Verschlüsselung, Authentifizierung und Netzwerkisolation.
Anpassen der Serialisierung und Deserialisierung
Die Anpassungsoptionen für die Serialisierung variieren je nach Sprache. Wählen Sie die Registerkarte "Sprache" aus, um die verfügbaren Optionen anzuzeigen.
Standardserialisierungslogik
Durable Functions für .NET verwendet im Prozess Json.NET zum Serialisieren von Orchestrierungs- und Entitätsdaten in JSON. Standardmäßig werden die folgenden Json.NET-Einstellungen verwendet:
Eingaben, Ausgaben und Zustand:
JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None,
DateParseHandling = DateParseHandling.None,
}
Ausnahmen:
JsonSerializerSettings
{
ContractResolver = new ExceptionResolver(),
TypeNameHandling = TypeNameHandling.Objects,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
}
Eine ausführlichere Dokumentation zu JsonSerializerSettings finden Sie hier.
Anpassen der Serialisierung mit .NET Attributen
Während der Serialisierung sucht Json.NET nach verschiedenen Attributen an Klassen und Eigenschaften, die steuern, wie die Daten serialisiert und aus JSON deserialisiert werden. Wenn Sie den Quellcode für den an die Durable Functions-APIs übergebenen Datentyp besitzen, sollten Sie dem Typ diese Attribute hinzufügen, um Serialisierung und Deserialisierung anzupassen.
Anpassen der Serialisierung mit Dependency Injection
Funktions-Apps, die auf .NET abzielen und auf der Funktions-V3-Laufzeit ausgeführt werden, können Dependency Injection (DI) verwenden, um anzupassen, wie Daten und Ausnahmen serialisiert werden. Im folgenden Beispielcode wird die Verwendung von DI zum Überschreiben der Standard-Json.NET Serialisierungseinstellungen mithilfe von benutzerdefinierten Implementierungen der IMessageSerializerSettingsFactory und IErrorSerializerSettingsFactory-Dienstschnittstellen veranschaulicht.
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System.Collections.Generic;
[assembly: FunctionsStartup(typeof(MyApplication.Startup))]
namespace MyApplication
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<IMessageSerializerSettingsFactory, CustomMessageSerializerSettingsFactory>();
builder.Services.AddSingleton<IErrorSerializerSettingsFactory, CustomErrorSerializerSettingsFactory>();
}
/// <summary>
/// A factory that provides the serialization for all inputs and outputs for activities and
/// orchestrations, as well as entity state.
/// </summary>
internal class CustomMessageSerializerSettingsFactory : IMessageSerializerSettingsFactory
{
public JsonSerializerSettings CreateJsonSerializerSettings()
{
// Return your custom JsonSerializerSettings here
}
}
/// <summary>
/// A factory that provides the serialization for all exceptions thrown by activities
/// and orchestrations
/// </summary>
internal class CustomErrorSerializerSettingsFactory : IErrorSerializerSettingsFactory
{
public JsonSerializerSettings CreateJsonSerializerSettings()
{
// Return your custom JsonSerializerSettings here
}
}
}
}