Bearbeiten

Freigeben über


Zuverlässiges Web-App-Muster für .NET – Anwenden des Musters

Azure App Service
Azure Front Door
Azure Cache for Redis
.NET

In diesem Artikel erfahren Sie, wie Sie das zuverlässige Web-App-Muster anwenden. Das zuverlässige Web-App-Muster besteht aus einer Reihe von Prinzipien und Implementierungstechniken, die definieren, wie Sie Web-Apps bei der Migration zur Cloud ändern (zu einer neuen Plattform verlagern) sollten. Es führt nur die Codeupdates durch, die für eine erfolgreiche Ausführung in der Cloud benötigt werden.

Um die Anwendung dieser Anleitung zu unterstützen, gibt es eine Referenzimplementierung des zuverlässigen Web-App-Musters, die Sie bereitstellen können.

Diagramm der Architektur der Referenzimplementierung.Architektur der Referenzimplementierung: Laden Sie eine Visio-Datei dieser Architektur herunter.

In der folgenden Anleitung wird die Referenzimplementierung als Beispiel verwendet. Zur Anwendung des zuverlässigen Web-App-Musters folgen Sie diesen Empfehlungen, die an den Säulen des Well-Architected Framework ausgerichtet sind:

Zuverlässigkeit

Zuverlässigkeit stellt sicher, dass Ihre Anwendung Ihre Verpflichtungen gegenüber den Kunden erfüllen kann. Weitere Informationen finden Sie unter Erstellen einer Checkliste zur Überprüfung der Zuverlässigkeit. Das zuverlässige Web-App-Muster führt zwei wesentliche Entwurfsmuster auf Code-Ebene ein, um die Zuverlässigkeit zu verbessern: das Wiederholungsmuster und das Trennschaltermuster.

Verwenden des Wiederholungsmusters

Das Wiederholungsmuster behandelt vorübergehende Dienstunterbrechungen (als vorübergebende Fehler bezeichnet), die in der Regel innerhalb von Sekunden gelöst werden können. Diese Fehler werden häufig durch Diensteinschränkungen, einen dynamischen Lastausgleich sowie Netzwerkprobleme in Cloudumgebungen verursacht. Die Implementierung des Wiederholungsmusters umfasst das erneute Senden fehlgeschlagener Anforderungen, die Zulassung konfigurierbarer Verzögerungen und die Durchführung mehrerer Versuche, bevor ein Fehler gemeldet wird.

Anwendungen, die das Wiederholungsmuster verwenden, sollten die Software Development Kits (SDKs) für Clients von Azure und dienstspezifische Wiederholungsmechanismen integrieren, um die Effizienz zu verbessern. Für Anwendungen, die dieses Muster nicht verwenden, sollte es anhand der folgenden Anleitung eingeführt werden.

Testen Sie zunächst den Azure-Dienst und die Client-SDKs.

Die meisten Azure-Dienste und Client-SDKs verfügen über einen integrierten Wiederholungsmechanismus. Sie sollten den integrierten Wiederholungsmechanismus für Azure-Dienste verwenden, um die Implementierung zu beschleunigen.

Beispiel: Die Referenzimplementierung verwendet die Verbindungsresilienz in Entity Framework Core, um das Wiederholungsmuster auf Anfragen für Azure SQL-Datenbank anzuwenden (siehe folgenden Code).

services.AddDbContextPool<ConcertDataContext>(options => options.UseSqlServer(sqlDatabaseConnectionString,
    sqlServerOptionsAction: sqlOptions =>
    {
        sqlOptions.EnableRetryOnFailure(
        maxRetryCount: 5,
        maxRetryDelay: TimeSpan.FromSeconds(3),
        errorNumbersToAdd: null);
    }));

Verwenden Sie die Polly-Bibliothek, wenn die Clientbibliothek keine Wiederholungen unterstützt.

Möglicherweise müssen Sie eine Abhängigkeit aufrufen, die kein Azure-Dienst ist oder das Wiederholungsmuster nicht nativ unterstützt. In diesem Fall sollten Sie die Polly-Bibliothek verwenden, um das Wiederholungsmuster zu implementieren. Polly ist eine .NET-Bibliothek für Resilienz und zur Behandlung vorübergehender Fehler. Damit können Sie Fluent-APIs verwenden, um das Verhalten an einem zentralen Ort der Anwendung zu beschreiben.

Beispiel: Die Referenzimplementierung verwendet Polly für die Einrichtung der ASP.NET Core-Abhängigkeitsinjektion. Polly erzwingt das Wiederholungsmuster jedes Mal, wenn der Code ein Objekt erstellt, welches das IConcertSearchService-Objekt aufruft. Im Polly-Framework wird dieses Verhalten als Richtlinie bezeichnet. Der Code extrahiert diese Richtlinie in der Methode GetRetryPolicy. Die Methode GetRetryPolicy wendet das Wiederholungsmuster jedes Mal an, wenn die Front-End-Web-App API Konzertsuchdienste aufruft (siehe folgenden Code).

private void AddConcertSearchService(IServiceCollection services)
{
    var baseUri = Configuration["App:RelecloudApi:BaseUri"];
    if (string.IsNullOrWhiteSpace(baseUri))
    {
        services.AddScoped<IConcertSearchService, MockConcertSearchService>();
    }
    else
    {
        services.AddHttpClient<IConcertSearchService, RelecloudApiConcertSearchService>(httpClient =>
        {
            httpClient.BaseAddress = new Uri(baseUri);
            httpClient.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
            httpClient.DefaultRequestHeaders.Add(HeaderNames.UserAgent, "Relecloud.Web");
        })
        .AddPolicyHandler(GetRetryPolicy())
        .AddPolicyHandler(GetCircuitBreakerPolicy());
    }
}

private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
    var delay = Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromMilliseconds(500), retryCount: 3);
    return HttpPolicyExtensions
      .HandleTransientHttpError()
      .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
      .WaitAndRetryAsync(delay);
}

Der Richtlinienhandler für die RelecloudApiConcertSearchService-Instanz wendet das Wiederholungsmuster auf alle Anforderungen an die API an. Er verwendet die HandleTransientHttpError-Logik, um HTTP-Anforderungen zu erkennen, die sicher wiederholt werden können, und dann, um die Anforderung basierend auf der Konfiguration zu wiederholen. Ein gewisses Maß an Zufälligkeit sorgt dafür, dass im Falle eines Fehlers der Datenverkehr an die API nicht zu stark ansteigt.

Verwenden des Sicherungsmusters

Die Kombination von Wiederholungs- und Trennschaltermuster erweitert die Fähigkeit einer Anwendung, Dienstunterbrechungen zu behandeln, die nicht im Zusammenhang mit vorübergehenden Fehlern stehen. Das Wiederholungsmuster verhindert, dass eine Anwendung kontinuierlich versucht, auf einen nicht reagierenden Dienst zuzugreifen. Das Trennschaltermuster gibt die Anwendung frei und vermeidet die Veröffentlichung von CPU-Zyklen, damit die Leistungsintegrität der Anwendung für Endbenutzer erhalten bleibt.

Beispiel: Die Referenzimplementierung fügt das Trennschaltermuster in der Methode GetCircuitBreakerPolicy hinzu (siehe folgenden Code).

private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
    return HttpPolicyExtensions
        .HandleTransientHttpError()
        .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
        .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}

Im Code wendet der Richtlinienhandler für die RelecloudApiConcertSearchService-Instanz das Trennschaltermuster auf alle Anfragen an die API an. Er verwendet die HandleTransientHttpError-Logik, um HTTP-Anforderungen zu erkennen, die sicher wiederholt werden können, begrenzt aber die Anzahl der aggregierten Fehler über einen bestimmten Zeitraum.

Sicherheit

Sicherheit bietet Schutz vor vorsätzlichen Angriffen und dem Missbrauch Ihrer wertvollen Daten und Systeme. Weitere Informationen finden Sie unter Erstellen einer Checkliste zur Überprüfung der Sicherheit. Das zuverlässige Web-App-Muster verwendet verwaltete Identitäten, um eine identitätsbasierte Sicherheit zu implementieren. Private Endpunkte, eine Webanwendungs-Firewall und ein eingeschränkter Zugriff auf die Web-App sorgen für Sicherheit in Bezug auf den eingehenden Datenverkehr.

Erzwingen der geringsten Rechte

Um die Sicherheit und Effizienz zu gewährleisten, sollten Sie Benutzer*innen (Benutzungsidentitäten) und Azure-Diensten (Workloadidentitäten) nur die jeweils notwendigen Berechtigungen gewähren.

Weisen Sie Benutzungsidentitäten Berechtigungen zu.

Untersuchen Sie die Anforderungen Ihrer Anwendung, um einen Satz von Rollen zu definieren, die alle Aktionen von Benutzer*innen abdecken, ohne sich zu überschneiden. Ordnen Sie die einzelnen Benutzer*innen der jeweils am besten geeigneten Rolle zu. Stellen Sie sicher, dass sie nur Zugriff auf das erhalten, was sie für ihre Aufgaben benötigen.

Weisen Sie Workloadidentitäten Berechtigungen zu.

Gewähren Sie nur die Berechtigungen, die für die Ausführung kritisch sind, z. B. CRUD-Aktionen in Datenbanken oder den Zugriff auf Geheimnisse. Die Berechtigungen für Workloadidentitäten sind persistent. Sie können Workloadidentitäten daher keine kurzfristigen oder Just-in-Time-Berechtigungen gewähren.

  • Sie sollten die rollenbasierte Zugriffssteuerung (Role Based Access Control, RBAC) verwenden. Beginnen Sie stets mit Azure RBAC, um Berechtigungen zuzuweisen. Sie ermöglicht eine präzise Steuerung und stellt sicher, dass der Zugriff überprüfbar und granular ist. Verwenden Sie Azure RBAC, um nur die Berechtigungen zu gewähren, die der jeweilige Dienst für die Ausführung der vorgesehenen Funktionen benötigt.

  • Ergänzen Sie dies mit einer Zugriffsteuerung auf Azure-Dienst-Ebene. Wenn Azure RBAC ein bestimmtes Szenario nicht abdeckt, ergänzen Sie sie mit Zugriffsrichtlinien auf Azure-Dienst-Ebene.

Konfigurieren der Benutzerauthentifizierung und -autorisierung

Authentifizierung und Autorisierung sind kritische Aspekte der Sicherheit von Webanwendungen. Authentifizierung ist der Prozess, bei dem die Identität eines Benutzers überprüft wird. Autorisierung gibt die Aktionen an, die ein Benutzer innerhalb der Anwendung ausführen darf. Das Ziel besteht darin, Authentifizierung und Autorisierung zu implementieren, ohne Ihren Sicherheitsstatus zu schwächen. Um dieses Ziel zu erreichen, müssen Sie die Features der Azure-Anwendungsplattform (Azure App Service) und des Identitätsanbieters (Microsoft Entra ID) verwenden.

Benutzerauthentifizierung konfigurieren

Sichern Sie Ihre Web-App, indem Sie die Authentifizierung von Benutzer*innen über die Funktionen Ihrer Plattform aktivieren. Azure App Service unterstützt die Authentifizierung mittels Identitätsanbietern wie Microsoft Entra ID. Damit wird der Authentifizierungs-Workload aus Ihrem Code ausgelagert.

Konfigurieren der Dienstauthentifizierung und -autorisierung

Konfigurieren Sie die Dienstauthentifizierung und -autorisierung so, dass die Dienste in Ihrer Umgebung die erforderlichen Berechtigungen für die Ausführung notwendiger Funktionen erhalten. Verwenden Sie Verwaltete Identitäten in Microsoft Entra ID, um die Erstellung und Verwaltung von Dienstidentitäten zu automatisieren. Dies beseitigt die Notwendigkeit für die manuelle Verwaltung von Anmeldeinformationen. Mit einer verwalteten Identität kann Ihre Web-App sicher auf Azure-Dienste zugreifen, z. B. Azure Key Vault und Datenbanken. Sie unterstützt darüber hinaus die Integration von CI/CD-Pipelines für Bereitstellungen zu Azure App Service. In Szenarien wie hybriden Bereitstellungen oder Bereitstellungen mit Legacy-Systemen sollten Sie Ihre lokalen Authentifizierungslösungen jedoch weiter verwenden, um die Migration zu vereinfachen. Wechseln Sie zu verwalteten Identitäten, wenn Ihr System für einen modernen Ansatz für die Identitätsverwaltung bereit ist. Weitere Informationen finden Sie unter Überwachung verwalteter Identitäten.

Verwenden Sie DefaultAzureCredential für die Einrichtung von Code.

Verwenden Sie DefaultAzureCredential, um Anmeldeinformationen für lokale Entwicklungsidentitäten und verwaltete Identitäten in der Cloud bereitzustellen. DefaultAzureCredential generiert ein TokenCredential für den Erwerb eines OAuth-Tokens. Es unterstützt die meisten Azure SDK-Szenarien und Microsoft-Clientbibliotheken. Es erkennt die Umgebung der Anwendung, um die richtige Identität zu verwenden, und fordert Zugriffstoken wie erforderlich an. DefaultAzureCredential optimiert die Authentifizierung für Anwendungen, die von Azure bereitgestellt werden. Weitere Informationen finden Sie unter DefaultAzureCredential.

Beispiel: Die Referenzimplementierung verwendet während des Starts die Klasse DefaultAzureCredential, um die Verwendung verwalteter Identitäten zwischen Web-API und Key Vault zu unterstützen (siehe folgenden Code).

builder.Configuration.AddAzureAppConfiguration(options =>
{
     options
        .Connect(new Uri(builder.Configuration["Api:AppConfig:Uri"]), new DefaultAzureCredential())
        .ConfigureKeyVault(kv =>
        {
            // Some of the values coming from Azure App Configuration are stored Key Vault. Use
            // the managed identity of this host for the authentication.
            kv.SetCredential(new DefaultAzureCredential());
        });
});

Verwenden Sie Infrastruktur als Code, um verwaltete Identitäten zu erstellen.

Sie sollten Bicep-Vorlagen verwenden, um die Azure-Infrastruktur zur Unterstützung verwalteter Identitäten zu erstellen und zu konfigurieren. Verwaltete Identitäten verwenden keine Geheimnisse oder Kennwörter, sodass Sie weder Key Vault noch eine Strategie für die Geheimnisrotation benötigen, um die Integrität sicherzustellen. Sie können die Verbindungszeichenfolgen im App Configuration-Dienst speichern.

Beispiel: Die Referenzimplementierung verwendet Bicep-Vorlagen, um (1) die verwaltete Identität zu erstellen, (2) die Identität mit der Web-App zu verknüpfen und (3) der Identität die Berechtigung zum Zugriff auf die SQL-Datenbank zu gewähren. Das Argument Authentication in der folgenden Verbindungszeichenfolge weist die Microsoft-Clientbibliothek an, eine Verbindung mit einer verwalteten Identität herzustellen (siehe folgenden Code).

    Server=tcp:my-sql-server.database.windows.net,1433;Initial Catalog=my-sql-database;Authentication=Active Directory Default

Weitere Informationen finden Sie unter Verbindungsherstellung mit SQL-Datenbank über App Service (.NET).

Verwenden Sie einen zentralen Geheimnisspeicher, um Geheimnisse zu verwalten.

Verwenden Sie Azure Key Vault, wenn Sie Ihre Anwendung zur Cloud migrieren, um alle Geheimnisse sicher zu speichern. Dieses zentrale Repository bietet sichere Speicherung, Schlüsselrotation, Zugriffsüberwachung und Überwachung für Dienste, die keine verwalteten Identitäten unterstützen. Für die Konfiguration von Anwendungen wird Azure App Configuration empfohlen.

Beispiel: Die Referenzimplementierung speichert die folgenden Geheimnisse in Key Vault: (1) Benutzername und Kennwort für die PostgreSQL-Datenbank, (2) das Redis Cache-Kennwort und (3) das Client-Geheimnis für Microsoft Entra ID, das mit der Microsoft Authentication Library (MSAL)-Implementierung verknüpft ist.

Fügen Sie Key Vault nicht in den HTTP-Anforderungsflow ein.

Laden Sie Geheimnisse aus Key Vault beim Starten der Anwendung, nicht während jeder einzelnen HTTP-Anforderung. Key Vault dient zum sicheren Speichern und Abrufen vertraulicher Daten während der Bereitstellung. Zugriffe mit hoher Häufigkeit innerhalb von HTTP-Anforderungen können die Durchsatzkapazitäten von Key Vault überschreiten, was zu Anforderungseinschränkungen und Fehlern mit dem HTTP-Statuscode 429 führt. Weitere Informationen finden Sie unter Key Vault-Transaktionslimits.

Verwenden Sie nur eine einzige Methode für den Zugriff auf Geheimnisse in Key Vault.

Beim Konfigurieren einer Web-App für den Zugriff auf Geheimnisse in Key Vault haben Sie zwei primäre Optionen:

  • App-Einstellung in App Service: Verwenden Sie eine App-Einstellung in App Service, um das Geheimnis direkt als Umgebungsvariable einzufügen.

  • Direkter Geheimnisverweis: Verweisen Sie im Anwendungscode direkt auf das Geheimnis. Fügen Sie in der Eigenschaftendatei Ihrer Anwendung einen spezifischen Verweis hinzu, z. B. application.properties für Java-Anwendungen, damit Ihre App mit Key Vault kommunizieren kann.

Es ist wichtig, eine dieser Methoden auszuwählen und aus Gründen der Einfachheit nur diese Methode zu verwenden und so eine unnötige Komplexität zu vermeiden.

Verwenden Sie bevorzugt temporäre Zugriffsmethoden.

Verwenden Sie temporäre Berechtigungen, um Ihre Anwendung vor unbefugtem Zugriff und Verstößen zu schützen. Verwenden Sie Shared Access Signatures (SASs) für den temporären Zugriff. Verwenden Sie SASs für die Benutzerdelegierung, um bei der Gewährung eines temporären Zugriffs die Sicherheit zu maximieren. Dies ist die einzige SAS, die Microsoft Entra-Anmeldeinformationen verwendet und keinen Speicherkontoschlüssel erfordert.

Verwenden privater Endpunkte

Verwenden Sie in allen Produktionsumgebungen für alle unterstützen Azure-Dienste private Endpunkte. Private Endpunkte stellen private Verbindungen zwischen Ressourcen in einem virtuellen Azure-Netzwerk und in Azure-Diensten bereit. Standardmäßig erfolgt die Kommunikation mit den meisten Azure-Diensten über das öffentliche Internet. Für private Endpunkte sind keine Codeänderungen, App-Konfigurationen oder Verbindungszeichenfolgen erforderlich. Weitere Informationen finden Sie unter Erstellen eines privaten Endpunkts und Bewährte Methoden für die Endpunktsicherheit.

Beispiel: Azure App Configuration, Azure SQL-Datenbank, Azure Cache for Redis, Azure Storage, Azure App Service und Key Vault verwenden einen privaten Endpunkt.

Verwenden Sie Web Application Firewall und schränken Sie den eingehenden Internetdatenverkehr ein.

Der gesamte eingehende Internetdatenverkehr an die Web-App muss über Web Application Firewall geleitet werden, um die Web-App vor häufigen Web-Exploits zu schützen. Setzen Sie die Leitung des gesamten eingehenden Internetdatenverkehrs über den öffentlichen Load Balancer (wenn vorhanden) und die Web Application Firewall durch.

Beispiel: Die Referenzimplementierung setzt die Leitung des gesamten eingehenden Internetdatenverkehrs über Front Door und Azure Web Application Firewall durch. Sie müssen in der Produktion den ursprünglichen HTTP-Hostnamen beibehalten.

Datenbanksicherheit konfigurieren

Der Datenbankzugriff auf Administratorebene gewährt Berechtigungen zum Ausführen privilegierter Vorgänge. Privilegierte Vorgänge umfassen das Erstellen und Löschen von Datenbanken, das Ändern von Tabellenschemas oder das Ändern von Benutzerberechtigungen. Entwickler benötigen häufig Zugriff auf Administratorebene, um die Datenbank zu verwalten oder Probleme zu behandeln.

  • Vermeiden Sie dauerhaft erhöhte Berechtigungen. Sie sollten den Entwicklern zur Durchführung privilegierter Vorgänge nur Just-in-Time-Zugriff gewähren. Mit einem Just-in-Time-Zugriff erhalten Benutzer*innen temporäre Berechtigungen für die Ausführung privilegierter Aufgaben.

  • Erteilen Sie der Anwendung keine erhöhten Berechtigungen. Sie sollten der Anwendungsidentität keinen Zugriff auf Administratorebene gewähren. Sie sollten den Zugriff der Anwendung auf die Datenbank mit den geringsten Berechtigungen konfigurieren. Dies begrenzt den Schadensradius von Fehlern und Sicherheitsverletzungen.

Kostenoptimierung

Bei der Kostenoptimierung geht es um die Suche nach Möglichkeiten, unnötige Ausgaben und den Verwaltungsoverhead zu reduzieren. Weitere Informationen finden Sie unter Erstellen einer Checkliste zur Überprüfung der Kostenoptimierung. Das zuverlässige Web-App-Muster implementiert Dimensionierungstechniken, die automatische Skalierung und die effiziente Ressourcennutzung, um eine stärker kostenoptimierte Web-App zu erhalten.

Richtige Größe der Ressourcen für jede Umgebung

Informieren Sie sich über die verschiedenen Leistungsstufen von Azure-Diensten, und verwenden Sie stets die richtige SKU für die Anforderungen der einzelnen Umgebungen. Produktionsumgebungen benötigen SKUs, die den Vereinbarungen zum Servicelevel (Service Level Agreements, SLA), Features und der Skalierung gerecht werden, die für die Produktion erforderlich sind. Nichtproduktionsumgebungen benötigen in der Regel jedoch nicht die gleiche Funktionalität. Ziehen Sie Azure Dev/Test-Preisoptionen, Azure Reservations und Azure-Compute-Sparpläne in Betracht, um zusätzliche Einsparungen zu erzielen.

Beispiel: Die Referenzimplementierung verwendet Bicep-Parameter, um Ressourcenbereitstellungskonfigurationen auszulösen. Einer dieser Parameter gibt die Ressourcenstufen (SKUs) an, die bereitgestellt werden sollen. Die Web-App verwendet die leistungsstärkeren und teureren SKUs für Produktionsumgebungen und die günstigeren SKUs für die Nichtproduktionsumgebung (siehe folgenden Code).

var redisCacheSkuName = isProd ? 'Standard' : 'Basic'
var redisCacheFamilyName = isProd ? 'C' : 'C'
var redisCacheCapacity = isProd ? 1 : 0

Verwenden der Autoskalierung

Die automatische Skalierung automatisiert die horizontale Skalierung für Produktionsumgebungen. Automatisches Skalieren auf der Grundlage von Leistungsmetriken. Leistungsauslöser für die CPU-Auslastung sind ein guter Ausgangspunkt, wenn Sie die Skalierungskriterien Ihrer Anwendung nicht kennen. Sie müssen Skalierungsauslöser (CPU, RAM, Netzwerk und Datenträger) konfigurieren und anpassen, um dem Verhalten Ihrer Webanwendung zu entsprechen. Skalieren Sie nicht vertikal, um häufigen Nachfrageänderungen zu entsprechen. Es ist weniger kosteneffizient. Weitere Informationen finden Sie unter Skalieren in Azure App Service und Autoskalierung in Microsoft Azure.

Beispiel: Die Referenzimplementierung verwendet die folgende Konfiguration in der Bicep-Vorlage. Eine Regel für die automatische Skalierung für Azure App Service wird erstellt. Die Regel wird auf bis zu 10 Instanzen skaliert und ist standardmäßig auf eine Instanz festgelegt. Sie verwendet die CPU-Auslastung als Auslöser für das Herunter- und Hochskalieren. Die Web-App-Hostingplattform wird bei einer CPU-Auslastung von 85 % hochskaliert und bei einer Auslastung von 60 % herunterskaliert. Die Einstellung für horizontale Skalierung von 85 % anstelle eines Prozentsatzes, der näher an 100 % liegt, bietet einen Puffer zum Schutz vor kumuliertem Benutzerdatenverkehr, der durch persistente Sitzungen verursacht wird. Sie schützt auch vor hohen Datenverkehrsbursts, indem sie frühzeitig skaliert, um eine maximale CPU-Auslastung zu vermeiden. Diese Regeln für die automatische Skalierung gelten nicht universell (siehe folgenden Code).

resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (autoScaleSettings != null) { 
  name: '${name}-autoscale' 
  location: location 
  tags: tags 
  properties: { 
    targetResourceUri: appServicePlan.id 
    enabled: true 
    profiles: [ 
      { 
        name: 'Auto created scale condition' 
        capacity: { 
          minimum: string(zoneRedundant ? 3 : autoScaleSettings!.minCapacity) 
          maximum: string(autoScaleSettings!.maxCapacity) 
          default: string(zoneRedundant ? 3 : autoScaleSettings!.minCapacity) 
        } 
        rules: [ 
          ... 
        ] 
      } 
    ] 
  } 
}

Verwenden Sie Ressourcen effizient.

  • Verwenden Sie gemeinsam genutzte Dienste. Die Zentralisierung und gemeinsame Nutzung bestimmter Ressourcen bedeutet eine Kostenoptimierung und einen geringeren Verwaltungsaufwand. Platzieren Sie gemeinsam genutzte Netzwerkressourcen im virtuellen Hubnetzwerk.

    Beispiel: Die Referenzimplementierung platziert Azure Firewall, Azure Bastion und Key Vault im virtuellen Hubnetzwerk.

  • Löschen Sie nicht verwendete Umgebungen. Löschen Sie Nichtproduktionsumgebungen nach dem Ende der normalen Geschäftszeiten oder an Feiertagen, um die Kosten zu optimieren. Sie können die Infrastruktur als Code verwenden, um Azure-Ressourcen und ganze Umgebungen zu löschen. Entfernen Sie die Deklaration der Ressource, die Sie aus der Bicep-Vorlage löschen möchten. Verwenden Sie den Was-Wäre-Wenn-Vorgang, um eine Vorschau der Änderungen anzuzeigen, bevor sie wirksam werden. Sichern Sie Daten, die Sie später benötigen. Informieren Sie sich über die Abhängigkeiten in Bezug auf die Ressource, die Sie löschen. Wenn es Abhängigkeiten gibt, müssen Sie diese Ressourcen möglicherweise aktualisieren oder ebenfalls entfernen. Weitere Informationen finden Sie unter Was-wäre-wenn-Vorgang für die Bicep-Bereitstellung.

  • Funktionalität für die gemeinsame Platzierung. Wenn genügend Kapazitäten vorhanden sind, können Sie Anwendungsressourcen und -funktionen gemeinsam in einer einzigen Azure-Ressource platzieren. Mehrere Web-Apps können beispielsweise einen einzelnen Server verwenden (App Service-Plan). Ein einzelner Zwischenspeicher kann beispielsweise mehrere Datentypen unterstützen.

    Beispiel: Die Referenzimplementierung verwendet eine einzelne Azure Cache for Redis-Instanz für die Sitzungsverwaltung sowohl in Front-End-Web-Apps (Speichern von Warenkorb- und MSAL-Token) als auch in Back-End-Web-Apps (mit den Daten bevorstehender Konzerte). Sie wählt die kleinste Redis-SKU aus, die mehr als die benötigte Kapazität bietet. Diese wird effizient genutzt, indem mehrere Datentypen verwendet werden, um die Kosten zu kontrollieren.

Optimaler Betrieb

Die Säule „Optimaler Betrieb“ deckt die Betriebsprozesse ab, die für die Bereitstellung einer Anwendung und deren Ausführung in der Produktion sorgen. Weitere Informationen finden Sie unter Erstellen einer Checkliste zur Überprüfung des optimalen Betriebs. Das zuverlässige Web-App-Muster implementiert Infrastruktur als Code für Infrastrukturbereitstellungen und zur Überwachung, um Einblicke zu bieten.

Automatisieren der Bereitstellung

Verwenden Sie eine CI/CD-Pipeline, um Änderungen bereitzustellen, von der Quellcodeverwaltung bis zur Produktion. Wenn Sie Azure DevOps verwenden, sollten Sie Azure Pipelines verwenden. Verwenden Sie GitHub-Aktionen, wenn Sie GitHub verwenden. Azure unterstützt ARM-Vorlagen (JSON), Bicep und Terraform und verfügt über Vorlagen für jede Azure-Ressource. Weitere Informationen finden Sie unter Bicep-, Azure Resource Manager- und Terraform-Vorlagen und Wiederholbare Infrastruktur.

Beispiel: Die Referenzimplementierung verwendet die Azure Dev CLI und Infrastruktur als Code (Bicep-Vorlagen), um Azure-Ressourcen zu erstellen, die Konfiguration einzurichten und die erforderlichen Ressourcen bereitzustellen.

Konfigurieren der Überwachung

Um Ihre Web-App zu überwachen, sammeln und analysieren Sie Metriken und Protokolle aus Ihrem Anwendungscode, aus Ihrer Infrastruktur (Laufzeit) und aus der Plattform (Azure-Ressourcen). Fügen Sie eine Diagnoseeinstellung für jede Azure-Ressource in Ihrer Architektur hinzu. Jeder Azure-Dienst verfügt über einen anderen Satz von Protokollen und Metriken, die Sie erfassen können. Weitere Informationen finden Sie unter Überwachen der Plattform und Überwachen von App Service.

Überwachen Sie die Baselinemetriken.

Verwenden Sie Azure Application Insights, um Baselinemetriken wie Anforderungsdurchsatz, durchschnittliche Anforderungsdauer, Fehler und die Abhängigkeitsüberwachung nachzuverfolgen. Verwenden Sie AddApplicationInsightsTelemetry aus dem NuGet-PaketMicrosoft.ApplicationInsights.AspNetCore, um die Sammlung von Telemetriedaten zu aktivieren. Weitere Informationen finden Sie unter Aktivieren der Telemetrie für Application Insights und Abhängigkeitsinjektion in .NET.

Beispiel: Die Referenzimplementierung verwendet Code, um Baselinemetriken in Application Insights zu konfigurieren (siehe folgenden Code).

public void ConfigureServices(IServiceCollection services)
{
   ...
   services.AddApplicationInsightsTelemetry(Configuration["App:Api:ApplicationInsights:ConnectionString"]);
   ...
}

Erstellen Sie angepasste Telemetriedaten wie erforderlich.

Verwenden Sie Application Insights für die Sammlung angepasster Telemetriedaten, um mehr über Ihre Web-App-Benutzer*innen zu erfahren. Erstellen Sie eine Instanz der Klasse TelemetryClient, und verwenden Sie die TelemetryClient-Methoden, um die richtige Metrik zu erstellen. Wandeln Sie die Abfrage in ein Azure-Dashboardgadget um.

Beispiel: Die Referenzimplementierung fügt Metriken hinzu, mit denen das Betriebsteam erkennen kann, ob die Web-App Transaktionen erfolgreich abschließt. Es wird überprüft, ob die Web-App online ist, indem überwacht wird, ob Kunden Bestellungen aufgeben können, und nicht, indem die Anzahl der Anforderungen oder die CPU-Auslastung gemessen wird. Die Referenzimplementierung verwendet TelemetryClient über Abhängigkeitsinjektion und die TrackEvent-Methode, um Telemetriedaten zu Ereignissen im Zusammenhang mit der Warenkorbaktivität zu sammeln. Die Telemetrie verfolgt die Tickets, die Benutzer*innen hinzufügen, entfernen und kaufen (siehe folgenden Code).

  • AddToCart zählt, wie häufig Benutzer*innen dem Warenkorb ein bestimmtes Ticket (ConcertID) hinzufügen.
  • RemoveFromCart erfasst Tickets, die Benutzer*innen aus dem Warenkorb entfernen.
  • CheckoutCart erfasst jedes Mal ein Ereignis, wenn Benutzer*innen ein Ticket kaufen.

this.telemetryClient.TrackEvent zählt die Tickets, die dem Warenkorb hinzugefügt wurden. Er stellt den Ereignisnamen (AddToCart) bereit und gibt ein Wörterbuch mit concertId und count an (siehe folgenden Code).

this.telemetryClient.TrackEvent("AddToCart", new Dictionary<string, string> {
    { "ConcertId", concertId.ToString() },
    { "Count", count.ToString() }
});

Weitere Informationen finden Sie unter:

Sammeln Sie protokollbasierte Metriken.

Verfolgen Sie protokollbasierte Metriken nach, um bessere Einblicke in wichtige Fragen der Anwendungsintegrität und Metriken zu erhalten. Sie können Abfragen in der Kusto-Abfragesprache (KQL) in Application Insights verwenden, um Daten zu suchen und zu organisieren. Weitere Informationen finden Sie unter Protokollbasierte Metriken von Azure Application Insights und Protokollbasierte und vorab aggregierte Metriken in Application Insights.

Aktivieren der Plattformdiagnose

Mit einer Diagnoseeinstellung in Azure können Sie die Plattformprotokolle und Metriken angeben, die Sie sammeln möchten, und wo sie gespeichert werden sollen. Plattformprotokolle sind integrierte Protokolle, die Diagnose- und Überprüfungsinformationen bereitstellen. Sie können Plattformdiagnosen für die meisten Azure-Dienste aktivieren, aber jeder Dienst definiert seine eigenen Protokollkategorien. Bei verschiedenen Azure-Diensten können Protokollkategorien ausgewählt werden.

  • Aktivieren Sie die Diagnose für alle unterstützten Dienste. Azure-Dienste erstellen Plattformprotokolle automatisch, aber der Dienst speichert sie nicht automatisch. Sie müssen die Diagnoseeinstellung für jeden Dienst aktivieren, und Sie sollten sie für jeden Azure-Dienst aktivieren, der Diagnose unterstützt.

  • Senden Sie Diagnosen an dasselbe Ziel wie die Anwendungsprotokolle. Wenn Sie Diagnosen aktivieren, wählen Sie die Protokolle aus, die Sie sammeln möchten, und wohin sie gesendet werden sollen. Sie sollten die Plattformprotokolle an dasselbe Ziel wie die Anwendungsprotokolle senden, damit Sie die beiden Datasets korrelieren können.

Effiziente Leistung

Leistungseffizienz ist die Fähigkeit Ihrer Workload, eine effiziente Skalierung entsprechend den Anforderungen der Benutzer auszuführen. Weitere Informationen finden Sie unter Erstellen einer Checkliste zur Überprüfung der Leistungseffizienz. Das zuverlässige Web-App-Muster verwendet das cachefremde Muster, um die Latenz für häufig angeforderte Daten zu minimieren.

Verwenden des cachefremden Musters

Das cachefremde Muster ist eine Strategie für die Zwischenspeicherung zur Verbesserung der Verwaltung von In-Memory-Daten. Das Muster weist der Anwendung die Verantwortung für die Verarbeitung von Datenanforderungen zu und stellt Konsistenz zwischen dem Zwischenspeicher und einem persistenten Speicher her, z. B. einer Datenbank. Wenn die Web-App eine Datenanforderung empfängt, durchsucht sie zuerst den Zwischenspeicher. Wenn die Daten fehlen, ruft sie diese aus der Datenbank ab, antwortet auf die Anforderung und aktualisiert den Zwischenspeicher entsprechend. Dieser Ansatz verkürzt die Reaktionszeiten, verbessert den Durchsatz und reduziert die Notwendigkeit für eine weitere Skalierung. Darüber hinaus ist der Dienst besser verfügbar, da die Auslastung des primären Datenspeichers reduziert wird und Ausfallrisiken minimiert werden.

Beispiel: Die Referenzimplementierung verbessert die Anwendungseffizienz durch die Zwischenspeicherung kritischer Daten, z. B. von Informationen zu bevorstehenden Konzerten, die für den Ticketverkauf von entscheidender Bedeutung sind. Sie verwendet den verteilten Speichercache von ASP.NET Core für die In-Memory-Speicherung von Elementen. Die Anwendung verwendet automatisch Azure Cache for Redis, wenn eine bestimmte Verbindungszeichenfolge entdeckt wird. Sie unterstützt außerdem lokale Entwicklungsumgebungen ohne Redis, um die Einrichtung zu vereinfachen und Kosten und Komplexität zu reduzieren. Die Methode (AddAzureCacheForRedis) konfiguriert die Anwendung für die Verwendung von Azure Cache for Redis. (siehe folgenden Code).

private void AddAzureCacheForRedis(IServiceCollection services)
{
    if (!string.IsNullOrWhiteSpace(Configuration["App:RedisCache:ConnectionString"]))
    {
        services.AddStackExchangeRedisCache(options =>
        {
            options.Configuration = Configuration["App:RedisCache:ConnectionString"];
        });
    }
    else
    {
        services.AddDistributedMemoryCache();
    }
}

Weitere Informationen finden Sie unter Verteiltes Zwischenspeichern in ASP.NET Core und AddDistributedMemoryCache-Methode.

Speichern Sie häufig abgerufene Daten im Zwischenspeicher.

Priorisieren Sie die Zwischenspeicherung für die am häufigsten abgerufenen Daten. Identifizieren Sie wichtige Datenpunkte, die Kundenbindung und Systemleistung fördern. Implementieren Sie Strategien für die Zwischenspeicherung speziell für diese Bereiche, um die Effektivität des cachefremden Musters zu optimieren. Dies reduziert die Latenz und die Datenbankauslastung erheblich. Verwenden Sie Azure Monitor, um die CPU, den Arbeitsspeicher und den Speicher der Datenbank nachzuverfolgen. Anhand dieser Metriken können Sie ermitteln, ob Sie eine kleinere Datenbank-SKU verwenden können.

Beispiel: Die Referenzimplementierung speichert die Daten für die bevorstehenden Konzerte zwischen. Auf der Seite „Bevorstehende Konzerte“ werden die meisten Abfragen an SQL-Datenbank erstellt und eine konsistente Ausgabe für jeden Besuch generiert. Das cachefremde Muster speichert die Daten nach der ersten Anforderung für diese Seite zwischen, um die Belastung der Datenbank zu verringern. Der folgende Code verwendet die GetUpcomingConcertsAsync-Methode, um Daten aus SQL-Datenbank in den Redis-Cache zu pullen. Die Methode füllt den Cache mit den neuesten Konzerten auf. Die Methode filtert nach Zeit, sortiert die Daten und gibt die Daten an den Controller zurück, um die Ergebnisse anzuzeigen (siehe folgenden Code).

public async Task<ICollection<Concert>> GetUpcomingConcertsAsync(int count)
{
    IList<Concert>? concerts;
    var concertsJson = await this.cache.GetStringAsync(CacheKeys.UpcomingConcerts);
    if (concertsJson != null)
    {
        // There is cached data. Deserialize the JSON data.
        concerts = JsonSerializer.Deserialize<IList<Concert>>(concertsJson);
    }
    else
    {
        // There's nothing in the cache. Retrieve data from the repository and cache it for one hour.
        concerts = await this.database.Concerts.AsNoTracking()
            .Where(c => c.StartTime > DateTimeOffset.UtcNow && c.IsVisible)
            .OrderBy(c => c.StartTime)
            .Take(count)
            .ToListAsync();
        concertsJson = JsonSerializer.Serialize(concerts);
        var cacheOptions = new DistributedCacheEntryOptions {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
        };
        await this.cache.SetStringAsync(CacheKeys.UpcomingConcerts, concertsJson, cacheOptions);
    }
    return concerts ?? new List<Concert>();
}

Halten Sie die Daten im Zwischenspeicher stets aktuell.

Planen Sie regelmäßige Aktualisierungen des Zwischenspeichers, um die Daten mit den neuesten Änderungen in der Datenbank zu synchronisieren. Ermitteln Sie die optimale Aktualisierungsrate basierend auf Datenvolatilität und Anforderungen der Benutzer*innen. Dieses Verfahren stellt sicher, dass die Anwendung das cachefremde Muster verwendet, um sowohl einen schnellen Zugriff als auch aktuelle Informationen bereitzustellen.

Beispiel: Die Referenzimplementierung speichert Daten nur für eine Stunde zwischen. Sie verfügt über einen Prozess zum Löschen des Cacheschlüssels, wenn sich die Daten ändern. Die Methode CreateConcertAsync löscht den Cacheschlüssel (siehe folgenden Code).

public async Task<CreateResult> CreateConcertAsync(Concert newConcert)
{
    database.Add(newConcert);
    await this.database.SaveChangesAsync();
    this.cache.Remove(CacheKeys.UpcomingConcerts);
    return CreateResult.SuccessResult(newConcert.Id);
}

Stellen Sie die Datenkonsistenz sicher.

Implementieren Sie Mechanismen zum Aktualisieren des Zwischenspeichers direkt nach jedem Schreibvorgang in der Datenbank. Verwenden Sie ereignisgesteuerte Updates oder dedizierte Datenverwaltungsklassen, um die Kohärenz des Zwischenspeichers sicherzustellen. Die konsistente Synchronisierung des Zwischenspeichers mit Datenbankänderungen ist für das cachefremde Muster von zentraler Bedeutung.

Beispiel: Die Referenzimplementierung verwendet die Methode UpdateConcertAsync, um die Daten im Zwischenspeicher konsistent zu halten (siehe folgenden Code).

public async Task<UpdateResult> UpdateConcertAsync(Concert existingConcert), 
{
   database.Update(existingConcert);
   await database.SaveChangesAsync();
   this.cache.Remove(CacheKeys.UpcomingConcerts);
   return UpdateResult.SuccessResult();
}

Testen Sie die Datenbankleistung.

Die Datenbankleistung kann sich auf die Leistung und Skalierbarkeit einer Anwendung auswirken. Es ist wichtig, die Leistung Ihrer Datenbank zu testen, um sicherzustellen, dass sie optimiert ist. Einige wichtige Überlegungen sind die Auswahl der richtigen Cloudregion, das Verbindungspooling, das cachefremde Muster (Cache-Aside) und die Optimierung von Abfragen.

  • Testen von Netzwerkhops. Das Verschieben einer Anwendung in die Cloud kann zu zusätzlichen Netzwerkhops und Wartezeiten in Ihrer Datenbank führen. Sie sollten auf zusätzliche Hops testen, die von der neuen Cloudumgebung eingeführt werden.

  • Ermitteln Sie eine Leistungsbasislinie. Sie sollten lokale Leistungsmetriken als anfängliche Baseline verwenden, um die Anwendungsleistung in der Cloud zu vergleichen.

Nächste Schritte

Stellen Sie die Referenzimplementierung bereit, indem Sie den Anweisungen im GitHub-Repository folgen. Verwenden Sie die folgenden Ressourcen, um mehr über .NET-Anwendungen, Web-Apps, bewährte Methoden für die Cloud und Migrationen zu erfahren.

Upgrade von .NET Framework-Anwendungen

Die Referenzimplementierung wird in einem App-Dienst bereitgestellt, der Windows ausführt wird, kann aber unter Linux ausgeführt werden. Mit der App Service-Windows-Plattform können Sie .NET Framework-Web-Apps in Azure verschieben, ohne auf neuere Frameworkversionen zu aktualisieren. Informationen zu Linux-App Service-Plänen oder neuen Features und Leistungsverbesserungen, die den neuesten Versionen von .NET hinzugefügt wurden, finden Sie im folgenden Leitfaden.

Einführung in Web-Apps in Azure

Eine praktische Einführung in .NET-Webanwendungen in Azure finden Sie in diesem Leitfaden zum Bereitstellen einer einfachen .NET-Webanwendung.

Bewährte Methoden für die Cloud

Anleitungen zur Einführung und Architektur von Azure finden Sie unter:

Informationen zu Anwendungen, die ein höheres SLO als das zuverlässige Web-App-Muster erfordern, finden Sie unter Unternehmenskritische Workloads.

Migrationsanleitung

Mit den folgenden Tools und Ressourcen können Sie lokale Ressourcen zu Azure migrieren.