Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här självstudien lär du dig hur du distribuerar en Orleans kundvagnsapp till Azure App Service. Den här guiden går igenom ett exempelprogram som stöder följande funktioner:
Kundvagn: Ett enkelt kundvagnsprogram som använder Orleans för sitt plattformsoberoende ramverksstöd och skalbara distribuerade programfunktioner.
- Inventeringshantering: Redigera och/eller skapa produktinventering.
- Butiksinventering: Utforska köpbara produkter och lägg dem i kundvagnen.
- Kundvagn: Visa en sammanfattning av alla objekt i kundvagnen och hantera dessa objekt genom att ta bort eller ändra antalet för varje objekt.
Med en förståelse för appen och dess funktioner lär du dig hur du distribuerar appen till Azure App Service med hjälp av GitHub Actions, .NET och Azure CLIs och Azure Bicep. Dessutom får du lära dig hur du konfigurerar det virtuella nätverket för appen i Azure.
I den här tutorialen lär du dig följande:
- Distribuera ett Orleans program till Azure App Service
- Automatisera distributionen med GitHub Actions och Azure Bicep
- Konfigurera det virtuella nätverket för appen i Azure
Förutsättningar
- Ett GitHub-konto
- Läs en introduktion till Orleans
- .NET 8 SDK
- Azure CLI
- En .NET-integrerad utvecklingsmiljö (IDE)
- Använd gärna Visual Studio eller Visual Studio Code
Köra appen lokalt
Om du vill köra appen lokalt förgrenar du Azure Samples: Orleans Cluster på Azure App Service-lagringsplatsen och klonar den till den lokala datorn. När du har klonat öppnar du lösningen i valfri IDE. Om du använder Visual Studio högerklickar du på Orleans. ShoppingCart.Silo-projekt , välj Ange som startprojekt och kör sedan appen. Annars kör du appen med följande .NET CLI-kommando:
dotnet run --project Silo\Orleans.ShoppingCart.Silo.csproj
Mer information finns i dotnet run. När appen körs navigerar du runt och testar dess funktioner. Alla appfunktioner när de körs lokalt förlitar sig på minnesintern beständighet och lokal klustring. Det använder också Bogus NuGet-paketet för att generera falska produkter. Stoppa appen antingen genom att välja alternativet Stoppa felsökning i Visual Studio eller genom att trycka på Ctrl+C i .NET CLI.
Inne i kundvagnsappen
Orleans är ett tillförlitligt och skalbart ramverk för att skapa distribuerade program. För denna handledning distribuerar du en enkel kundvagnsapp byggd med Orleans till Azure App Service. Appen gör det möjligt att hantera lager, lägga till och ta bort objekt i en kundvagn och handla tillgängliga produkter. Klienten skapas med Blazor med en servervärdsmodell. Appen är skapad på följande sätt:
Föregående diagram visar att klienten är Blazor-appen på serversidan. Den består av flera tjänster som använder ett motsvarande Orleans korn. Varje tjänst parkopplas med ett Orleans korn enligt följande:
-
InventoryService
: AnvänderIInventoryGrain
där lagret är partitionerat efter produktkategori. -
ProductService
: Förbrukar denIProductGrain
där en enskild produkt är bunden till en instans av ett enda korn genomId
. -
ShoppingCartService
: Förbrukar denIShoppingCartGrain
där en enskild användare bara har en enda kundvagnsinstans oavsett vilka kunder som konsumerar.
Lösningen innehåller tre projekt:
-
Orleans.ShoppingCart.Abstractions
: Ett klassbibliotek som definierar modeller och gränssnitt för appen. -
Orleans.ShoppingCart.Grains
: Ett klassbibliotek som definierar de komponenter som implementerar appens affärslogik. -
Orleans.ShoppingCart.Silos
: En server-side Blazor-app som värdar Orleans-silon.
Klientanvändarupplevelsen
Kundvagnsklientappen har flera sidor som var och en representerar en annan användarupplevelse. Appens användargränssnitt skapas med hjälp av NuGet-paketet MudBlazor .
Startsida
Några enkla fraser hjälper dig att förstå appens syfte och lägga till kontext i varje navigeringsmenyalternativ.
Butiksinventeringssida
En sida som visar alla produkter som är tillgängliga att köpa. Objekt kan läggas till i kundvagnen från den här sidan.
Tom kundvagnssida
Om inget har lagts till i kundvagnen återger sidan ett meddelande som anger att inga objekt finns i kundvagnen.
Objekt som lagts till i kundvagnen på butiksinventeringssidan
När objekt läggs till i kundvagnen på butiksinventeringssidan visar appen ett meddelande som anger att objektet har lagts till.
Produkthanteringssidan
Hantera inventering från den här sidan. Produkter kan läggas till, redigeras och tas bort från lagret.
Skapa ny dialogruta för produkthantering
När du klickar på knappen Skapa ny produkt visas en dialogruta där du kan skapa en ny produkt.
Objekt på kundvagnssidan
När objekten finns i kundvagnen visar du dem, ändrar deras kvantitet och tar till och med bort dem. En sammanfattning av artiklarna i kundvagnen och den totala kostnaden före skatt visas.
Viktigt!
När den här appen körs lokalt i en utvecklingsmiljö använder den localhost-kluster, minnesintern lagring och en lokal silo. Det sår också lagret med falsk data som genereras automatiskt med hjälp av Bogus NuGet-paketet. Detta är avsiktligt för att demonstrera funktioner.
Översikt över distribution
Orleans program är utformade för att skala upp och skala ut effektivt. För att åstadkomma detta kommunicerar programinstanser direkt via TCP-socketar. Orleans kräver nätverksanslutning mellan silor, därför. Azure App Service stöder detta krav via integrering av virtuella nätverk och ytterligare konfiguration som instruerar App Service att allokera privata nätverksportar för appinstanser.
När du distribuerar Orleans till Azure App Service vidtar du följande åtgärder för att säkerställa att värdarna kan kommunicera:
- Aktivera integrering av virtuella nätverk genom att följa guiden Aktivera integrering med ett virtuellt Azure-nätverk .
- Konfigurera appen med privata portar med hjälp av Azure CLI enligt beskrivningen i avsnittet Konfigurera antal privata portar med Hjälp av Azure CLI . Bicep-mallen i avsnittet Utforska Bicep-mallarna nedan visar hur du konfigurerar den här inställningen via Bicep.
- Om du distribuerar till Linux kontrollerar du att värdarna lyssnar på alla IP-adresser enligt beskrivningen i avsnittet Konfigurera värdnätverk .
Konfigurera antal privata portar med Hjälp av Azure CLI
az webapp config set -g '<resource-group-name>' --subscription '<subscription-id>' -n '<app-service-app-name>' --generic-configurations '{\"vnetPrivatePortsCount\": "2"}'
Konfigurera värdnätverk
När du har konfigurerat Azure App Service med integrering av virtuellt nätverk (VNet) och ställt in den för att tillhandahålla programinstanser med minst två privata portar vardera, tillhandahålls ytterligare två miljövariabler till dina appprocesser: WEBSITE_PRIVATE_IP
och WEBSITE_PRIVATE_PORTS
. Dessa variabler innehåller två viktiga informationsdelar:
- Vilken IP-adress andra värdar i det virtuella nätverket kan använda för att kontakta en viss appinstans. och
- Vilka portar på ip-adressen dirigeras till den appinstansen
Variabeln WEBSITE_PRIVATE_IP
anger en IP-routningsbar ip-adress från det virtuella nätverket, men inte nödvändigtvis en IP-adress som appinstansen direkt kan binda till. Därför ska du instruera värden att binda till alla interna adresser genom att skicka listenOnAnyHostAddress: true
till metodens anrop ConfigureEndpoints
. I följande exempel konfigureras en ISiloBuilder
instans för att använda de inmatade miljövariablerna och lyssna på rätt gränssnitt:
var endpointAddress = IPAddress.Parse(builder.Configuration["WEBSITE_PRIVATE_IP"]!);
var strPorts = builder.Configuration["WEBSITE_PRIVATE_PORTS"]!.Split(',');
if (strPorts.Length < 2)
{
throw new Exception("Insufficient private ports configured.");
}
var (siloPort, gatewayPort) = (int.Parse(strPorts[0]), int.Parse(strPorts[1]));
siloBuilder
.ConfigureEndpoints(endpointAddress, siloPort, gatewayPort, listenOnAnyHostAddress: true)
Koden ovan finns också i Azure Samples: Orleans Cluster på Azure App Service-lagringsplatsen , vilket gör det möjligt att visa den i kontexten för resten av värdkonfigurationen.
Distribuera till Azure App Service
Ett typiskt Orleans program består av ett kluster av serverprocesser (silor) där kornen finns och en uppsättning klientprocesser (vanligtvis webbservrar) som tar emot externa begäranden, omvandlar dem till kornmetodanrop och returnerar resultat. För att köra ett Orleans-program är första steget att starta ett kluster med silor. I testsyfte kan ett kluster bestå av en enda silo.
Anmärkning
För en tillförlitlig produktionsdistribution skulle du vilja ha mer än en silo i ett kluster för feltolerans och skalning.
Innan du distribuerar appen skapar du en Azure-resursgrupp (eller så kan du använda en befintlig). Om du vill skapa en ny Azure-resursgrupp använder du någon av följande artiklar:
Anteckna namnet på resursgruppen som du väljer. du behöver den senare för att distribuera appen.
Skapa ett huvudnamn för tjänsten
För att automatisera appens distribution måste du skapa ett huvudnamn för tjänsten. Det här är ett Microsoft-konto som har behörighet att hantera Azure-resurser åt dig.
az ad sp create-for-rbac --sdk-auth --role Contributor \
--name "<display-name>" --scopes /subscriptions/<your-subscription-id>
JSON-autentiseringsuppgifterna som skapas ser ut ungefär så här, men med faktiska värden för din klient, prenumeration och klientorganisation:
{
"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"
}
Kopiera kommandots utdata till urklipp och fortsätt till nästa steg.
Skapa en GitHub-hemlighet
GitHub tillhandahåller en mekanism för att skapa krypterade hemligheter. Hemligheterna du skapar är tillgängliga för användning i GitHub Actions-arbetsflöden. Du ser hur du använder GitHub Actions för att automatisera appens distribution tillsammans med Azure Bicep. Bicep är ett domänspecifikt språk (DSL) som använder deklarativ syntax för att distribuera Azure-resurser. Mer information finns i Vad är Bicep?. Med hjälp av utdata från steget Skapa en tjänsthuvudnamn måste du skapa en GitHub-hemlighet med namnet AZURE_CREDENTIALS
med JSON-formaterade autentiseringsuppgifter.
På din GitHub-lagringsplats väljer du Inställningar>Hemligheter>Skapa en ny hemlighet. Ange namnet AZURE_CREDENTIALS
och klistra in JSON-autentiseringsuppgifterna från föregående steg i fältet Värde .
Mer information finns i GitHub: Krypterade hemligheter.
Förbereda för Azure-distribution
Paketera appen för distribution.
Orleans.ShoppingCart.Silos
I projektet definieras ett Target
element som körs efter Publish
steget. Detta mål zippar publiceringskatalogen till en silo.zip-fil:
<Target Name="ZipPublishOutput" AfterTargets="Publish">
<Delete Files="$(ProjectDir)\..\silo.zip" />
<ZipDirectory SourceDirectory="$(PublishDir)" DestinationFile="$(ProjectDir)\..\silo.zip" />
</Target>
Det finns många sätt att distribuera en .NET-app till Azure App Service. I den här självstudien använder du GitHub Actions, Azure Bicep och .NET och Azure CLIs. Överväg filen ./github/workflows/deploy.yml i roten på GitHub-lagringsplatsen:
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 8.0
uses: actions/setup-dotnet@v3
with:
dotnet-version: 8.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
- name: Staging deploy
run: |
az webapp deploy --name ${{ env.UNIQUE_APP_NAME }} \
--slot ${{ env.UNIQUE_APP_NAME }}stg \
--resource-group ${{ env.AZURE_RESOURCE_GROUP_NAME }} \
--clean true --restart true \
--type zip --src-path silo.zip --debug
Föregående GitHub-arbetsflöde gör följande:
- Publicerar kundvagnsappen som en zip-fil med hjälp av dotnet-publiceringskommandot .
- Loggar in på Azure med autentiseringsuppgifter från steget Skapa ett huvudnamn för tjänsten .
- Utvärderar filen main.bicep och startar en distributionsgrupp med hjälp av az deployment group create.
- Distribuerar silo.zip-filen till Azure App Service med az webapp deploy.
- En ytterligare distribution till stagingmiljön är också konfigurerad.
Arbetsflödet utlöses vid en push till grenen main
. Mer information finns i GitHub Actions och .NET.
Tips/Råd
Om du stöter på problem när du kör arbetsflödet kan du behöva kontrollera att tjänstens huvudnamn har alla nödvändiga providernamnområden registrerade. Följande providernamnområden krävs:
Microsoft.Web
Microsoft.Network
Microsoft.OperationalInsights
Microsoft.Insights
Microsoft.Storage
Mer information finns i Lösa fel för registrering av resursprovider.
Azure tillämpar namngivningsbegränsningar och konventioner för resurser. Uppdatera värdena i filen deploy.yml för följande miljövariabler:
UNIQUE_APP_NAME
AZURE_RESOURCE_GROUP_NAME
AZURE_RESOURCE_GROUP_LOCATION
Ange dessa värden till ditt unika appnamn och namnet och platsen för azure-resursgruppen.
Mer information finns i Namngivningsregler och begränsningar för Azure-resurser.
Utforska Bicep-mallarna
az deployment group create
När kommandot körs utvärderas filen main.bicep. Den här filen innehåller De Azure-resurser som ska distribueras. Tänk på det här steget som att tillhandahålla alla resurser för distribution.
Viktigt!
Om du använder Visual Studio Code förbättras bicep-skrivupplevelsen när du använder Bicep-tillägget.
Det finns många Bicep-filer som var och en innehåller antingen resurser eller moduler (samlingar med resurser). Filen main.bicep är startpunkten och består främst av module
definitioner:
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',
'192.168.0.0/16'
]
}
subnets: [
{
name: 'default'
properties: {
addressPrefix: '172.17.0.0/24'
delegations: [
{
name: 'delegation'
properties: {
serviceName: 'Microsoft.Web/serverFarms'
}
}
]
}
}
{
name: 'staging'
properties: {
addressPrefix: '192.168.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
stagingSubnetId: vnet.properties.subnets[1].id
appInsightsConnectionString: logsModule.outputs.appInsightsConnectionString
appInsightsInstrumentationKey: logsModule.outputs.appInsightsInstrumentationKey
storageConnectionString: storageModule.outputs.connectionString
}
}
Föregående Bicep-fil definierar följande:
- Två parametrar för resursgruppens namn och appnamnet.
- Definitionen
storageModule
, som definierar lagringskontot. - Definitionen
logsModule
, som definierar Azure Log Analytics- och Application Insights-resurserna. - Resursen
vnet
, som definierar det virtuella nätverket. - Definitionen
siloModule
, som definierar Azure App Service.
En mycket viktig resource
är det virtuella nätverket. Med resursen vnet
kan Azure App Service kommunicera med Orleans klustret.
När en module
påträffas i Bicep-filen utvärderas den via en annan Bicep-fil som innehåller resursdefinitionerna. Den första modulen som påträffades är storageModule
, definierad i filen storage.bicep :
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-filer accepterar parametrar som deklareras med hjälp av nyckelordet param
. På samma sätt kan de deklarera utdata med hjälp av nyckelordet output
. Lagringen resource
förlitar sig på Microsoft.Storage/storageAccounts@2021-08-01
typen och versionen. Den provisioneras på platsen för resursgruppen som en StorageV2
och Standard_LRS
SKU. Bicep-filen för lagring definierar anslutningssträngen som en output
. Detta connectionString
används senare av silo Bicep-filen för att ansluta till lagringskontot.
Därefter definierar logs-and-insights.bicep-filen Azure Log Analytics- och Application Insights-resurserna:
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
Den här Bicep-filen definierar Azure Log Analytics- och Application Insights-resurserna. Resursen appInsights
är en web
typ och resursen logs
är en PerGB2018
typ. Både appInsights
och logs
resurser etableras på resursgruppens plats. Resursen appInsights
länkar till resursen logs
via egenskapen WorkspaceResourceId
. Den här Bicep-filen definierar två utdata som används senare av App Service module
.
Slutligen definierar filen app-service.bicep Azure App Service-resursen:
param appName string
param location string
param vnetSubnetId string
param stagingSubnetId 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: 'v8.0'
appSettings: [
{
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
value: appInsightsInstrumentationKey
}
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: appInsightsConnectionString
}
{
name: 'ORLEANS_AZURE_STORAGE_CONNECTION_STRING'
value: storageConnectionString
}
{
name: 'ORLEANS_CLUSTER_ID'
value: 'Default'
}
]
alwaysOn: true
}
}
}
resource stagingSlot 'Microsoft.Web/sites/slots@2022-03-01' = {
name: '${appName}stg'
location: location
properties: {
serverFarmId: appServicePlan.id
virtualNetworkSubnetId: stagingSubnetId
siteConfig: {
http20Enabled: true
vnetPrivatePortsCount: 2
webSocketsEnabled: true
netFrameworkVersion: 'v8.0'
appSettings: [
{
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
value: appInsightsInstrumentationKey
}
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: appInsightsConnectionString
}
{
name: 'ORLEANS_AZURE_STORAGE_CONNECTION_STRING'
value: storageConnectionString
}
{
name: 'ORLEANS_CLUSTER_ID'
value: 'Staging'
}
]
alwaysOn: true
}
}
}
resource slotConfig 'Microsoft.Web/sites/config@2021-03-01' = {
name: 'slotConfigNames'
parent: appService
properties: {
appSettingNames: [
'ORLEANS_CLUSTER_ID'
]
}
}
resource appServiceConfig 'Microsoft.Web/sites/config@2021-03-01' = {
parent: appService
name: 'metadata'
properties: {
CURRENT_STACK: 'dotnet'
}
}
Den här Bicep-filen konfigurerar Azure App Service som ett .NET 8-program. Både appServicePlan
och appService
resurser etableras på resursgruppens plats. Resursen appService
är konfigurerad för att använda SKU:n S1
med en kapacitet på 1
. Dessutom är resursen konfigurerad för att använda vnetSubnetId
undernätet och HTTPS. Också konfigurerar den appInsightsInstrumentationKey
instrumentationsnyckeln, samt anslutningssträngarna appInsightsConnectionString
och storageConnectionString
. Kundvagnsappen använder dessa värden.
Det ovan nämnda Visual Studio Code-tillägget för Bicep innehåller en visualiserare. Alla dessa Bicep-filer visualiseras på följande sätt:
Mellanlagringsmiljöer
Distributionsinfrastrukturen kan distribueras till mellanlagringsmiljöer. Dessa är kortlivade, testcentrerade, oföränderliga testmiljöer som är mycket användbara för att testa utplaceringar innan de flyttas till produktion.
Anmärkning
Om App Service körs i Windows måste varje App Service ha en egen separat App Service-plan. Du kan också undvika den här konfigurationen genom att använda App Service på Linux i stället, och det här problemet är löst.
Sammanfattning
När källkoden uppdateras och ändringar skickas push
till main
lagringsplatsens gren körs deploy.yml arbetsflödet. Den tilldelar de resurser som definierats i Bicep-filer och distribuerar applikationen. Programmet kan utökas till att omfatta nya funktioner, till exempel autentisering, eller för att stödja flera instanser. Det primära målet med det här arbetsflödet är att demonstrera möjligheten att etablera och distribuera resurser i ett enda steg.
Förutom visualiseraren från Bicep-tillägget ser resursgruppssidan i Azure-portalen ut ungefär som i följande exempel efter etablering och distribution av programmet: