Distribuera Orleans till Azure App Service
I den här självstudien får du lära dig hur du distribuerar en kundvagnsapp i Orleans för att Azure App Service. Självstudien vägleder dig genom ett exempelprogram som stöder följande funktioner:
Kundvagn: Ett enkelt kundvagnsprogram som använder Orleans för sitt plattformsoberoende ramverksstöd och dess skalbara distribuerade programfunktioner.
- Lagerhantering: 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. antingen ta bort eller ändra kvantiteten för varje objekt.
Med en förståelse för appen och dess funktioner får du lära dig hur du distribuerar appen till Azure App Service med hjälp av GitHub Actions, .NET och Azure CLI:er 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 guiden får du lära dig att:
- 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
Krav
- Ett GitHub-konto
- Läs en introduktion till Orleans
- .NET 7 SDK
- Azure CLI
- En .NET-integrerad utvecklingsmiljö (IDE)
- Du kan använda Visual Studio eller Visual Studio Code
Köra appen lokalt
Om du vill köra appen lokalt förgrenar du Azure Samples: Orleans-klustret på Azure App Service lagringsplats och klonar det 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å projektet Orleans.ShoppingCart.Silo och väljer Ange som startprojekt och kör sedan appen. Annars kan du köra 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 kan du navigera runt och du kan testa dess funktioner. Alla funktioner i appen när den körs lokalt förlitar sig på minnesintern persistens, lokal klustring och använder 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.
Inuti kundvagnsappen
Orleans är ett tillförlitligt och skalbart ramverk för att skapa distribuerade program. I den här självstudien distribuerar du en enkel kundvagnsapp som skapats med hjälp av Orleans för att Azure App Service. Appen visar möjligheten att hantera inventering, lägga till och ta bort artiklar i en kundvagn och handla tillgängliga produkter. Klienten skapas med Blazor med en servervärdmodell. Appen är konstruerad 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 förbrukar ett motsvarande Orleans-korn. Varje tjänst parkopplas med ett Orleans-korn enligt följande:
InventoryService
: Förbrukar varIInventoryGrain
lagret partitioneras efter produktkategori.ProductService
: Förbrukar därIProductGrain
en enskild produkt är bunden till en instans med en enda kornighet avId
.ShoppingCartService
: Förbrukar denIShoppingCartGrain
där en enskild användare bara har en enda kundvagnsinstans oavsett vilken kundanvändning som används.
Lösningen innehåller tre projekt:
Orleans.ShoppingCart.Abstractions
: Ett klassbibliotek som definierar modellerna och gränssnitten för appen.Orleans.ShoppingCart.Grains
: Ett klassbibliotek som definierar kornigheterna som implementerar appens affärslogik.Orleans.ShoppingCart.Silos
: En Blazor-app på serversidan som är värd för Orleans silo.
Klientanvändarupplevelsen
Kundvagnsklientappen har flera sidor, som var och en representerar olika användarupplevelser. Appens användargränssnitt skapas med MudBlazor NuGet-paketet .
Startsida
Några enkla fraser som användaren kan använda för att förstå appens syfte och lägga till kontext i varje navigeringsmenyobjekt.
Butiksinventeringssida
En sida som visar alla produkter som är tillgängliga för köp. Objekt kan läggas till i kundvagnen från den här sidan.
Tom kundvagnssida
När du inte har lagt till något i kundvagnen visas ett meddelande på sidan som anger att du inte har några artiklar i kundvagnen.
Artiklar som lagts till i kundvagnen på butiksinventeringssidan
När artiklar läggs till i kundvagnen på butiksinventeringssidan visar appen ett meddelande som anger att objektet har lagts till i kundvagnen.
Sidan Produkthantering
En användare kan hantera inventering från den här sidan. Produkter kan läggas till, redigeras och tas bort från lagret.
Dialogrutan Skapa ny sida för produkthantering
När en användare klickar på knappen Skapa ny produkt visar appen en dialogruta där användaren kan skapa en ny produkt.
Objekt på kundvagnssidan
När artiklarna finns i kundvagnen kan du visa dem och ändra deras kvantitet och till och med ta bort dem från kundvagnen. Användaren visas en sammanfattning av artiklarna i kundvagnen och den totala kostnaden före skatt.
Viktigt
När den här appen körs lokalt i en utvecklingsmiljö använder appen localhost-klustring, minnesintern lagring och en lokal silo. Inventeringen får också falska data som genereras automatiskt med hjälp av Bogus NuGet-paketet . Allt detta är avsiktligt för att demonstrera funktionaliteten.
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. Därför är det första man behöver göra för att köra ett Orleans-program att starta ett kluster med silor. I testsyfte kan ett kluster bestå av en enda silo.
Anteckning
För en tillförlitlig produktionsdistribution vill du ha mer än en silo i ett kluster för feltolerans och skalning.
Innan du distribuerar appen måste du skapa en Azure-resursgrupp (eller välja att 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 det senare för att distribuera appen.
Skapa ett huvudnamn för tjänsten
För att automatisera distributionen av appen 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. De hemligheter som du skapar är tillgängliga för användning i GitHub Actions arbetsflöden. Du kommer att se hur GitHub Actions kan användas för att automatisera distributionen av appen tillsammans med Azure Bicep. Bicep är ett domänspecifikt språk (DSL) som använder en deklarativ syntax för att distribuera Azure-resurser. Mer information finns i Vad är Bicep. Med hjälp av utdata från steget Skapa ett huvudnamn för tjänsten måste du skapa en GitHub-hemlighet med namnet AZURE_CREDENTIALS
med JSON-formaterade autentiseringsuppgifter.
På GitHub-lagringsplatsen 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: Encrypted Secrets (GitHub: Krypterade hemligheter).
Förbereda för Azure-distribution
Appen måste paketeras för distribution. Orleans.ShoppingCart.Silos
I projektet definierar vi ett Target
element som körs efter stegetPublish
. Då zippar du publiceringskatalogen i 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-CLI:er. Ö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 7.0
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.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 kommer att:
- Publicera kundvagnsappen som en zip-fil med hjälp av kommandot dotnet publish .
- Logga in på Azure med autentiseringsuppgifterna från steget Skapa ett huvudnamn för tjänsten .
- Utvärdera filen main.bicep och starta en distributionsgrupp med az deployment group create.
- Distribuera silo.zip-filen till Azure App Service med az webapp deploy.
- En ytterligare distribution till mellanlagring konfigureras också.
Arbetsflödet utlöses av en push-överföring till huvudgrenen . Mer information finns i GitHub Actions och .NET.
Tips
Om du får 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 vid registrering av resursprovider.
Azure tillämpar namngivningsbegränsningar och konventioner för resurser. Du måste uppdatera deploy.yml-filvärdena för följande:
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 din Azure-resursgrupp.
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 du vill distribuera. Ett sätt att tänka på det här steget är att det etablerar alla resurser för distribution.
Viktigt
Om du använder Visual Studio Code förbättras bicep-redigeringsupplevelsen 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 Virtual Network. Resursen vnet
gör det möjligt för Azure App Service att 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 var storageModule
, som definieras 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 också deklarera utdata med hjälp av nyckelordet output
. Lagringen resource
förlitar sig på Microsoft.Storage/storageAccounts@2021-08-01
typen och versionen. Den etableras på resursgruppens plats, som en StorageV2
och Standard_LRS
SKU. Lagrings-bicep definierar dess anslutningssträng som en output
. Detta connectionString
används senare av silo-bicep för att ansluta till lagringskontot.
Därefter definierar filen logs-and-insights.bicep resurserna för Azure Log Analytics och 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
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 resursen appInsights
och resursen logs
etableras på resursgruppens plats. Resursen appInsights
är länkad till resursen logs
via WorkspaceResourceId
egenskapen . Det finns två utdata som definierats i denna bicep, som används senare av App Service module
.
Slutligen definierar filen app-service.bicep den 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: 'v6.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: 'v7.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 7-program. Både resursen appServicePlan
och resursen appService
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 för att använda HTTPS. Den konfigurerar appInsightsInstrumentationKey
också instrumentationsnyckeln, anslutningssträngen appInsightsConnectionString
och anslutningssträngen storageConnectionString
. Dessa används av kundvagnsappen.
Det tidigare 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, som är kortvariga, testcentrerade och oföränderliga utkastsmiljöer. Dessa miljöer är mycket användbara för att testa distributioner innan de flyttas till produktion.
Anteckning
Om din App Service körs i Windows måste varje App Service ha en egen separat App Service plan. Om du vill undvika den här konfigurationen kan du i stället använda App Service på Linux och det här problemet kan lösas.
Sammanfattning
När du uppdaterar källkoden och push
ändringarna main
i lagringsplatsens gren körs arbetsflödet deploy.yml . Den tillhandahåller de resurser som definierats i bicep-filerna och distribuerar programmet. Programmet kan utökas till att omfatta nya funktioner, till exempel autentisering, eller för att stödja flera instanser av programmet. 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 skulle sidan Azure Portal-resursgrupp se ut ungefär som i följande exempel efter etablering och distribution av programmet: