Bereitstellen von Orleans auf Azure App Service

In diesem Lernprogramm erfahren Sie, wie Sie eine Orleans-Einkaufswagen-App für Azure App Service bereitstellen. Das Lernprogramm führt Sie durch eine Beispielanwendung, die die folgenden Features unterstützt:

  • Einkaufswagen: Eine einfache Einkaufswagenanwendung, die Orleans für seine plattformübergreifende Framework-Unterstützung und seine skalierbaren verteilten Anwendungsfunktionen verwendet.

    • Bestandsverwaltung: Bearbeiten und/oder Erstellen des Produktbestands.
    • Shopbestand: Erkunden Sie bereinigungsfähige Produkte und fügen Sie sie zu Ihrem Warenkorb hinzu.
    • Warenkorb: Anzeigen einer Zusammenfassung aller Artikel in Ihrem Warenkorb und Verwalten dieser Artikel; entfernen oder ändern die Menge der einzelnen Elemente.

Mit einem Verständnis der App und seiner Features erfahren Sie dann, wie Sie die Azure App Service App mithilfe von GitHub Actions, der .NET- und Azure-CLIs und Azure Bicep bereitstellen. Darüber hinaus erfahren Sie, wie Sie das virtuelle Netzwerk für die App in Azure konfigurieren.

In diesem Tutorial lernen Sie Folgendes:

  • Bereitstellen einer Orleans-Anwendung für Azure App Service
  • Automatisieren der Bereitstellung mithilfe von GitHub Actions und Azure Bicep
  • Konfigurieren des virtuellen Netzwerks für die App in Azure

Voraussetzungen

Lokales Ausführen der App

Um die App lokal auszuführen, verzweigen Sie die Azure Samples: Orleans Cluster auf Azure App Service Repository, und klonen Sie sie auf Ihrem lokalen Computer. Öffnen Sie nach dem Klonen die Lösung in einer IDE Ihrer Wahl. Wenn Sie Visual Studio verwenden, klicken Sie mit der rechten Maustaste auf das Projekt Orleans.ShoppingCart.Silo , und wählen Sie " Als Startprojekt festlegen" aus, und führen Sie die App aus. Andernfalls können Sie die App mit dem folgenden .NET CLI-Befehl ausführen:

dotnet run --project Silo\Orleans.ShoppingCart.Silo.csproj

Weitere Informationen finden Sie unter dotnet run. Wenn die App ausgeführt wird, können Sie navigieren und ihre Funktionen testen. Alle Funktionen der App bei der lokalen Ausführung basieren auf der In-Memory-Persistenz, lokalen Clustering und verwendet das Bogus NuGet-Paket , um gefälschte Produkte zu generieren. Beenden Sie die App entweder, indem Sie die Option " Debuggen beenden" in Visual Studio auswählen oder STRG+C in der .NET CLI drücken.

Innerhalb der Einkaufswagen-App

Orleans ist ein zuverlässiges und skalierbares Framework für die Erstellung verteilter Anwendungen. Für dieses Lernprogramm stellen Sie eine einfache Einkaufswagen-App bereit, die mithilfe von Orleans erstellt wurde, um Azure App Service. Die App macht die Möglichkeit verfügbar, Inventar zu verwalten, Artikel in einem Warenkorb hinzuzufügen und zu entfernen und verfügbare Produkte zu kaufen. Der Client wird mithilfe von Blazor mit einem Serverhostingmodell erstellt. Die App wird wie folgt entwickelt:

Orleans: Beispiel-App-Architektur des Einkaufswagens.

Das vorherige Diagramm zeigt, dass der Client die serverseitige Blazor-App ist. Es besteht aus mehreren Diensten, die ein entsprechendes Orleans-Getreide verbrauchen. Jede Servicepaare mit einem Orleans-Getreide wie folgt:

  • InventoryService: Verwendet den Speicherort, in dem IInventoryGrain der Bestand nach Produktkategorie partitioniert wird.
  • ProductService: Verbraucht die Stelle, an der IProductGrain ein einzelnes Produkt an eine einzelne Getreideinstanz Idgebunden wird.
  • ShoppingCartService: Nutzt den IShoppingCartGrain Ort, an dem ein einzelner Benutzer nur eine einzelne Einkaufswageninstanz hat, unabhängig von der Nutzung von Kunden.

Die Lösung enthält drei Projekte:

  • Orleans.ShoppingCart.Abstractions: Eine Klassenbibliothek, die die Modelle und die Schnittstellen für die App definiert.
  • Orleans.ShoppingCart.Grains: Eine Klassenbibliothek, die die Getreide definiert, die die Geschäftslogik der App implementieren.
  • Orleans.ShoppingCart.Silos: Eine serverseitige Blazor-App, die das Orleans-Silo hosten.

Die Clientbenutzerumgebung

Die Einkaufswagen-Client-App verfügt über mehrere Seiten, von denen jede eine andere Benutzererfahrung darstellt. Die Benutzeroberfläche der App wird mithilfe des MudBlazor NuGet-Pakets erstellt.

Startseite

Einige einfache Ausdrücke für den Benutzer, um den Zweck der App zu verstehen, und fügen Sie jedem Navigationsmenüelement Kontext hinzu.

Orleans: Einkaufswagen-Beispiel-App, Startseite.

Shopbestandsseite

Eine Seite, auf der alle Produkte angezeigt werden, die zum Kauf verfügbar sind. Elemente können dem Warenkorb von dieser Seite hinzugefügt werden.

Orleans: Einkaufswagen-Beispiel-App, Shop-Bestandsseite.

Leere Warenkorbseite

Wenn Sie Ihrem Warenkorb nichts hinzugefügt haben, rendert die Seite eine Nachricht, die angibt, dass Sie keine Elemente in Ihrem Warenkorb haben.

Orleans: Einkaufswagen-Beispiel-App, leere Warenkorbseite.

Artikel, die dem Warenkorb hinzugefügt wurden, während auf der Shopbestandsseite

Wenn Artikel zu Ihrem Warenkorb hinzugefügt werden, während sie auf der Shopbestandsseite angezeigt werden, zeigt die App eine Meldung an, die angibt, dass das Element dem Warenkorb hinzugefügt wurde.

Orleans: Einkaufswagen-Beispiel-App, Artikel, die zum Warenkorb hinzugefügt wurden, während auf der Shop-Inventarseite.

Produktverwaltungsseite

Ein Benutzer kann den Bestand auf dieser Seite verwalten. Produkte können hinzugefügt, bearbeitet und aus dem Bestand entfernt werden.

Orleans: Einkaufswagen-Beispiel-App, Produktverwaltungsseite.

Produktverwaltungsseite zum Erstellen eines neuen Dialogfelds

Wenn ein Benutzer auf die Schaltfläche " Neues Produkt erstellen " klickt, zeigt die App ein Dialogfeld an, mit dem der Benutzer ein neues Produkt erstellen kann.

Orleans: Einkaufswagen-Beispiel-App, Produktverwaltungsseite – Neues Produktdialogfeld erstellen.

Artikel auf der Warenkorbseite

Wenn Sich Artikel in Ihrem Warenkorb befinden, können Sie sie anzeigen und ihre Menge ändern und sogar aus dem Warenkorb entfernen. Der Benutzer wird eine Zusammenfassung der Artikel im Warenkorb und die Vortax-Gesamtkosten angezeigt.

Orleans: Einkaufswagen-Beispiel-App, Artikel auf der Warenkorbseite.

Wichtig

Wenn diese App lokal ausgeführt wird, verwendet die App in einer Entwicklungsumgebung lokales Clustering, Speicher im Arbeitsspeicher und ein lokales Silo. Es samen auch den Bestand mit gefälschten Daten, die automatisch mithilfe des Bogus NuGet-Pakets generiert werden. Dies ist alles absichtlich, um die Funktionalität zu veranschaulichen.

Bereitstellen in Azure App Service

Eine typische Orleans-Anwendung besteht aus einem Cluster von Serverprozessen (Silos), bei denen Getreide leben und eine Reihe von Clientprozessen, in der Regel Webserver, die externe Anforderungen empfangen, sie in Getreidemethodenaufrufe umwandeln und Ergebnisse zurückgeben. Daher muss man zunächst eine Orleans-Anwendung ausführen, um einen Cluster von Silos zu starten. Für Testzwecke kann ein Cluster aus einem einzigen Silo bestehen.

Hinweis

Für eine zuverlässige Produktionsbereitstellung möchten Sie mehr als ein Silo in einem Cluster für Fehlertoleranz und Skalierung.

Bevor Sie die App bereitstellen, müssen Sie eine Azure-Ressourcengruppe erstellen (oder sie können eine vorhandene verwenden). Verwenden Sie einen der folgenden Artikel, um eine neue Azure-Ressourcengruppe zu erstellen:

Notieren Sie sich den von Ihnen ausgewählten Ressourcengruppennamen, müssen Sie es später benötigen, um die App bereitzustellen.

Erstellen eines Dienstprinzipals

Um die Bereitstellung der App zu automatisieren, müssen Sie einen Dienstprinzipal erstellen. Dies ist ein Microsoft-Konto, das über die Berechtigung zum Verwalten von Azure-Ressourcen in Ihrem Auftrag verfügt.

az ad sp create-for-rbac --sdk-auth --role Contributor \
  --name "<display-name>"  --scopes /subscriptions/<your-subscription-id>

Die erstellten JSON-Anmeldeinformationen sehen wie folgt aus, aber mit tatsächlichen Werten für Ihren Client, Ihr Abonnement und Ihren Mandanten:

{
  "clientId": "<your client id>",
  "clientSecret": "<your client secret>",
  "subscriptionId": "<your subscription id>",
  "tenantId": "<your tenant id>",
  "activeDirectoryEndpointUrl": "https://login.microsoftonline.com/",
  "resourceManagerEndpointUrl": "https://brazilus.management.azure.com",
  "activeDirectoryGraphResourceId": "https://graph.windows.net/",
  "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
  "galleryEndpointUrl": "https://gallery.azure.com",
  "managementEndpointUrl": "https://management.core.windows.net"
}

Kopieren Sie die Ausgabe des Befehls in die Zwischenablage, und fahren Sie mit dem nächsten Schritt fort.

Erstellen eines GitHub-Geheimnisses.

GitHub bietet einen Mechanismus zum Erstellen verschlüsselter Schlüssel. Die geheimen Schlüssel, die Sie erstellen, stehen in GitHub Actions Workflows zur Verfügung. Sie werden sehen, wie GitHub Actions verwendet werden können, um die Bereitstellung der App in Verbindung mit Azure Bicepzu automatisieren. Bicep ist eine domänenspezifische Sprache (DSL), die eine deklarative Syntax zum Bereitstellen von Azure-Ressourcen verwendet. Weitere Informationen finden Sie unter "Was ist Bicep". Mithilfe der Ausgabe aus dem Schritt "Dienstprinzipal erstellen" müssen Sie einen GitHub-Geheimschlüssel AZURE_CREDENTIALS mit den JSON-formatierten Anmeldeinformationen erstellen.

Wählen Sie im GitHub-Repository "Einstellungen>Geheime Schlüssel>erstellen" einen neuen geheimen Schlüssel aus. Geben Sie den Namen AZURE_CREDENTIALS ein, und fügen Sie die JSON-Anmeldeinformationen aus dem vorherigen Schritt in das Feld "Wert " ein.

GitHub-Repository: Einstellungen Geheime Schlüssel >

Weitere Informationen finden Sie unter GitHub: Verschlüsselte Geheimnisse.

Vorbereiten der Azure-Bereitstellung

Die App muss für die Bereitstellung verpackt werden. Orleans.ShoppingCart.Silos Im Projekt definieren wir ein Target Element, das nach dem Publish Schritt ausgeführt wird. Dadurch wird das Veröffentlichungsverzeichnis in eine silo.zipDatei zippt :

<Target Name="ZipPublishOutput" AfterTargets="Publish">
    <Delete Files="$(ProjectDir)\..\silo.zip" />
    <ZipDirectory SourceDirectory="$(PublishDir)" DestinationFile="$(ProjectDir)\..\silo.zip" />
</Target>

Es gibt viele Möglichkeiten, eine .NET-App für Azure App Service bereitzustellen. In diesem Lernprogramm verwenden Sie GitHub Actions, Azure Bicep und die .NET- und Azure-CLIs. Berücksichtigen Sie die Datei ./github/workflows/deploy.yml im Stammverzeichnis des GitHub-Repositorys:

name: Deploy to Azure App Service

on:
  push:
    branches:
    - main

env:
  UNIQUE_APP_NAME: cartify
  AZURE_RESOURCE_GROUP_NAME: orleans-resourcegroup
  AZURE_RESOURCE_GROUP_LOCATION: centralus

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Setup .NET 6.0
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: 6.0.x

    - name: .NET publish shopping cart app
      run: dotnet publish ./Silo/Orleans.ShoppingCart.Silo.csproj --configuration Release

    - name: Login to Azure
      uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}
    
    - name: Flex bicep
      run: |
        az deployment group create \
          --resource-group ${{ env.AZURE_RESOURCE_GROUP_NAME }} \
          --template-file '.github/workflows/flex/main.bicep' \
          --parameters location=${{ env.AZURE_RESOURCE_GROUP_LOCATION }} \
            appName=${{ env.UNIQUE_APP_NAME }} \
          --debug

    - name: Webapp deploy
      run: |
        az webapp deploy --name ${{ env.UNIQUE_APP_NAME }} \
          --resource-group ${{ env.AZURE_RESOURCE_GROUP_NAME  }} \
          --clean true --restart true \
          --type zip --src-path silo.zip --debug

Der vorherige GitHub-Workflow wird:

Der Workflow wird durch einen Push an den Hauptzweig ausgelöst. Weitere Informationen finden Sie unter GitHub Actions und .NET.

Tipp

Wenn Beim Ausführen des Workflows Probleme auftreten, müssen Sie möglicherweise überprüfen, ob der Dienstprinzipal alle erforderlichen Anbieternamespaces registriert hat. Die folgenden Anbieternamespaces sind erforderlich:

  • Microsoft.Web
  • Microsoft.Network
  • Microsoft.OperationalInsights
  • Microsoft.Insights
  • Microsoft.Storage

Weitere Informationen finden Sie unter Beheben von Fehlern für die Registrierung des Ressourcenanbieters.

Azure legt Benennungseinschränkungen und Konventionen für Ressourcen fest. Sie müssen die Dateiwerte "deploy.yml " für Folgendes aktualisieren:

  • UNIQUE_APP_NAME
  • AZURE_RESOURCE_GROUP_NAME
  • AZURE_RESOURCE_GROUP_LOCATION

Legen Sie diese Werte auf Ihren eindeutigen App-Namen und Ihren Azure-Ressourcengruppennamen und -speicherort fest.

Weitere Informationen finden Sie unter Benennungsregeln und -einschränkungen für Azure-Ressourcen.

Erkunden der Bicep-Vorlagen

Wenn der az deployment group create Befehl ausgeführt wird, wird die Datei "main.bicep " ausgewertet. Diese Datei enthält die Azure-Ressourcen, die Sie bereitstellen möchten. Eine Möglichkeit, diesen Schritt zu berücksichtigen, besteht darin, dass alle Ressourcen für die Bereitstellung vorgesehen sind.

Wichtig

Wenn Sie Visual Studio Code verwenden, wird die Bicep-Dokumenterstellung verbessert, wenn Sie die Bicep-Erweiterung verwenden.

Es gibt viele Bicep-Dateien, die entweder Ressourcen oder Module (Sammlungen von Ressourcen) enthalten. Die Datei "main.bicep " ist der Einstiegspunkt und besteht hauptsächlich aus module Definitionen:

param appName string
param location string = resourceGroup().location

module storageModule 'storage.bicep' = {
  name: 'orleansStorageModule'
  params: {
    name: '${appName}storage'
    location: location
  }
}

module logsModule 'logs-and-insights.bicep' = {
  name: 'orleansLogModule'
  params: {
    operationalInsightsName: '${appName}-logs'
    appInsightsName: '${appName}-insights'
    location: location
  }
}

resource vnet 'Microsoft.Network/virtualNetworks@2021-05-01' = {
  name: '${appName}-vnet'
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        '172.17.0.0/16'
      ]
    }
    subnets: [
      {
        name: 'default'
        properties: {
          addressPrefix: '172.17.0.0/24'
          delegations: [
            {
              name: 'delegation'
              properties: {
                serviceName: 'Microsoft.Web/serverFarms'
              }
            }
          ]
        }
      }
    ]
  }
}

module siloModule 'app-service.bicep' = {
  name: 'orleansSiloModule'
  params: {
    appName: appName
    location: location
    vnetSubnetId: vnet.properties.subnets[0].id
    appInsightsConnectionString: logsModule.outputs.appInsightsConnectionString
    appInsightsInstrumentationKey: logsModule.outputs.appInsightsInstrumentationKey
    storageConnectionString: storageModule.outputs.connectionString
  }
}

Die vorherige bicep-Datei definiert Folgendes:

  • Zwei Parameter für den Ressourcengruppennamen und den App-Namen.
  • Die storageModule Definition, die das Speicherkonto definiert.
  • Die logsModule Definition, die die Azure Log Analytics- und Application Insights-Ressourcen definiert.
  • Die vnet Ressource, die das virtuelle Netzwerk definiert.
  • Die siloModule Definition, die die Azure App Service definiert.

Eine sehr wichtige resource ist das der Virtual Network. Die vnet Ressource ermöglicht es dem Azure App Service, mit dem Orleans-Cluster zu kommunizieren.

Wenn in der Bicep-Datei ein module Fehler auftritt, wird sie über eine andere Bicep-Datei ausgewertet, die die Ressourcendefinitionen enthält. Das erste aufgetretene Modul war das storageModule, das in der Datei "storage.bicep " definiert ist:

param name string
param location string

resource storage 'Microsoft.Storage/storageAccounts@2021-08-01' = {
  name: name
  location: location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}

var key = listKeys(storage.name, storage.apiVersion).keys[0].value
var protocol = 'DefaultEndpointsProtocol=https'
var accountBits = 'AccountName=${storage.name};AccountKey=${key}'
var endpointSuffix = 'EndpointSuffix=${environment().suffixes.storage}'

output connectionString string = '${protocol};${accountBits};${endpointSuffix}'

Bicep-Dateien akzeptieren Parameter, die mithilfe des Schlüsselworts param deklariert werden. Ebenso können sie die Ausgaben auch mithilfe des output Schlüsselworts deklarieren. Der Speicher resource basiert auf dem Typ und der Microsoft.Storage/storageAccounts@2021-08-01 Version. Sie wird an der Position der Ressourcengruppe als StorageV2 SKU Standard_LRS bereitgestellt. Der Speicherbicep definiert seine Verbindungszeichenfolge als .output Dies connectionString wird später von der Silo-Bicep verwendet, um eine Verbindung mit dem Speicherkonto herzustellen.

Als Nächstes definiert die Datei "logs-and-insights.bicep " die Ressourcen "Azure Log Analytics" und "Application Insights":

param operationalInsightsName string
param appInsightsName string
param location string

resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
  name: appInsightsName
  location: location
  kind: 'web'
  properties: {
    Application_Type: 'web'
    WorkspaceResourceId: logs.id
  }
}

resource logs 'Microsoft.OperationalInsights/workspaces@2021-06-01' = {
  name: operationalInsightsName
  location: location
  properties: {
    retentionInDays: 30
    features: {
      searchVersion: 1
    }
    sku: {
      name: 'PerGB2018'
    }
  }
}

output appInsightsInstrumentationKey string = appInsights.properties.InstrumentationKey
output appInsightsConnectionString string = appInsights.properties.ConnectionString

Diese Bicep-Datei definiert die Azure Log Analytics- und Application Insights-Ressourcen. Die appInsights Ressource ist ein web Typ, und die logs Ressource ist ein PerGB2018 Typ. Sowohl die appInsights Ressource als auch die logs Ressource werden am Standort der Ressourcengruppe bereitgestellt. Die appInsights Ressource wird über die Eigenschaft mit der logsWorkspaceResourceId Ressource verknüpft. In dieser Bicep sind zwei Ausgaben definiert, die später von der App Service moduleverwendet werden.

Schließlich definiert die Datei "app-service.bicep" die Azure App Service Ressource:

param appName string
param location string
param vnetSubnetId string
param appInsightsInstrumentationKey string
param appInsightsConnectionString string
param storageConnectionString string

resource appServicePlan 'Microsoft.Web/serverfarms@2021-03-01' = {
  name: '${appName}-plan'
  location: location
  kind: 'app'
  sku: {
    name: 'S1'
    capacity: 1
  }
}

resource appService 'Microsoft.Web/sites@2021-03-01' = {
  name: appName
  location: location
  kind: 'app'
  properties: {
    serverFarmId: appServicePlan.id
    virtualNetworkSubnetId: vnetSubnetId
    httpsOnly: true
    siteConfig: {
      vnetPrivatePortsCount: 2
      webSocketsEnabled: true
      netFrameworkVersion: 'v6.0'
      appSettings: [
        {
          name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
          value: appInsightsInstrumentationKey
        }
        {
          name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
          value: appInsightsConnectionString
        }
        {
          name: 'ORLEANS_AZURE_STORAGE_CONNECTION_STRING'
          value: storageConnectionString
        }
      ]
      alwaysOn: true
    }
  }
}

resource appServiceConfig 'Microsoft.Web/sites/config@2021-03-01' = {
  name: '${appService.name}/metadata'
  properties: {
    CURRENT_STACK: 'dotnet'
  }
}

Diese Bicep-Datei konfiguriert die Azure App Service als .NET 6-Anwendung. Sowohl die appServicePlan Ressource als auch die appService Ressource werden am Standort der Ressourcengruppe bereitgestellt. Die appService Ressource ist so konfiguriert, dass die S1 SKU mit einer Kapazität von 1. Darüber hinaus ist die Ressource so konfiguriert, dass das vnetSubnetId Subnetz verwendet wird und HTTPS verwendet wird. Außerdem wird der appInsightsInstrumentationKey Instrumentierungsschlüssel, die appInsightsConnectionString Verbindungszeichenfolge und die storageConnectionString Verbindungszeichenfolge konfiguriert. Diese werden von der Einkaufswagen-App verwendet.

Die oben genannte Visual Studio Code-Erweiterung für Bicep enthält einen Visualizer. Alle diese Bicep-Dateien werden wie folgt visualisiert:

Orleans: Shopping Cart Sample App Bicep Provisioning Visualizer Rendering.

Zusammenfassung

Während Sie den Quellcode aktualisieren und push die main Verzweigung des Repositorys ändern, wird der deploy.yml-Workflow ausgeführt. Es stellt die in den Bicep-Dateien definierten Ressourcen bereit und stellt die Anwendung bereit. Die Anwendung kann erweitert werden, um neue Features, z. B. Authentifizierung, oder mehrere Instanzen der Anwendung zu unterstützen. Das primäre Ziel dieses Workflows besteht darin, die Fähigkeit zur Bereitstellung und Bereitstellung von Ressourcen in einem einzigen Schritt zu veranschaulichen.

Neben der Visualisierer aus der Bicep-Erweiterung würde die Azure-Portal Ressourcengruppenseite nach der Bereitstellung und Bereitstellung der Anwendung ähnlich aussehen:

Azure Portal: Orleans Einkaufswagen-Beispiel-App-Ressourcen.

Siehe auch