Развертывание Orleans в Служба приложений Azure

В этом руководстве описано, как развернуть приложение корзины для покупок Orleans в Служба приложений Azure. В этом руководстве описывается пример приложения, который поддерживает следующие функции:

  • Корзина покупок. Простое приложение корзины для покупок, которое использует Orleans для поддержки кроссплатформенной платформы и возможностей масштабируемых распределенных приложений.

    • Управление запасами: изменение и (или) создание инвентаризации продуктов.
    • Инвентаризация магазинов: изучите покупаемые продукты и добавьте их в корзину.
    • Корзина: просмотрите сводку по всем элементам в корзине и управляйте этими элементами; удаление или изменение количества каждого элемента.

Познакомьтесь с приложением и его функциями, вы узнаете, как развернуть приложение для Служба приложений Azure с помощью GitHub Actions, .NET и azure CLIs, а также Azure Bicep. Кроме того, вы узнаете, как настроить виртуальную сеть для приложения в Azure.

В этом руководстве описано следующее:

  • Развертывание приложения Orleans в Служба приложений Azure
  • Автоматизация развертывания с помощью GitHub Actions и Azure Bicep
  • Настройка виртуальной сети для приложения в Azure

Предварительные требования

Локальный запуск приложения

Чтобы запустить приложение локально, вилка кластера Azure Samples: Orleans в репозитории Служба приложений Azure и клонировать его на локальный компьютер. После клона откройте решение в выбранной интегрированной среде разработки. Если вы используете Visual Studio, щелкните правой кнопкой мыши проект Orleans.ShoppingCart.Silo и выберите пункт Наставить как запускаемый проект, а затем запустите приложение. В противном случае можно запустить приложение с помощью следующей команды CLI .NET:

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

Дополнительные сведения см. в разделе dotnet run. Работая с приложением, вы можете перемещаться, и вы можете протестировать его возможности. Все функциональные возможности приложения при локальном запуске зависят от сохраняемости в памяти, локальных кластеризация и используют пакет NuGet Bogus для создания поддельных продуктов. Остановите приложение, выбрав параметр Остановить отладку в Visual Studio или нажав клавиши CTRL+C в .NET CLI.

Внутри приложения корзины для покупок

Orleans — это надежная и масштабируемая платформа для создания распределенных приложений. В этом руководстве вы развернете простое приложение корзины для покупок, созданное с помощью Orleans для Служба приложений Azure. Приложение предоставляет возможность управлять запасами, добавлять и удалять элементы в корзине, а также совершать покупки доступных продуктов. Клиент создается с помощью Blazor с моделью размещения сервера. Приложение разработано следующим образом:

Orleans: пример архитектуры приложения корзины для покупок.

На предыдущей схеме показано, что клиент является серверным приложением Blazor. Он состоит из нескольких служб, потребляющих соответствующую зерну Орлеана. Каждая служба связывается с элементом управления Orleans следующим образом:

  • InventoryService: использует , где инвентаризация IInventoryGrain секционируется по категориям продуктов.
  • ProductService: использует , IProductGrain где один продукт привязывается к одному экземпляру grain с помощью Id.
  • ShoppingCartService: использует , IShoppingCartGrain где один пользователь имеет только один экземпляр корзины для покупок независимо от потребления клиентов.

Это решение содержит три проекта:

  • Orleans.ShoppingCart.Abstractions: библиотека классов, которая определяет модели и интерфейсы для приложения.
  • Orleans.ShoppingCart.Grains: библиотека классов, определяющая объекты grain, реализующие бизнес-логику приложения.
  • Orleans.ShoppingCart.Silos: серверное приложение Blazor, в котором размещается хранилище Orleans.

Взаимодействие с пользователем клиента

Клиентское приложение корзины для покупок содержит несколько страниц, каждая из которых представляет разные возможности пользователя. Пользовательский интерфейс приложения создается с помощью пакета NuGet MudBlazor .

Домашняя страница

Несколько простых фраз, чтобы пользователь понимал назначение приложения и добавлял контекст к каждому элементу меню навигации.

Orleans: пример приложения Корзина покупок, домашняя страница.

Страница инвентаризации магазинов

Страница со всеми продуктами, доступными для покупки. Элементы можно добавить в корзину с этой страницы.

Orleans: Пример приложения корзины для покупок, страница инвентаризации магазинов.

Пустая страница корзины

Если вы ничего не добавили в корзину, на странице отображается сообщение о том, что в корзине нет элементов.

Orleans: пример приложения

Товары, добавленные в корзину на странице инвентаризации магазина

Когда товары добавляются в корзину на странице инвентаризации магазина, приложение отображает сообщение о том, что товар был добавлен в корзину.

Orleans: пример приложения Корзина для покупок, элементы, добавленные в корзину на странице запасов магазина.

Страница управления продуктами

Пользователь может управлять запасами на этой странице. Продукты можно добавлять, изменять и удалять из запасов.

Orleans: пример приложения корзины для покупок, страница управления продуктами.

Диалоговое окно создания страницы управления продуктами

Когда пользователь нажимает кнопку Создать продукт , приложение отображает диалоговое окно, позволяющее пользователю создать новый продукт.

Orleans: пример приложения корзины покупок, страница управления продуктами — диалоговое окно создания нового продукта.

Элементы на странице корзины

Когда товары находятся в вашей корзине, вы можете просмотреть их и изменить их количество, и даже удалить их из корзины. Пользователю отображается сводка по товарам в корзине и суммарные затраты.

Orleans: пример приложения корзины для покупок, элементы на странице корзины.

Важно!

Когда это приложение запускается локально в среде разработки, оно будет использовать localhost кластеризация, хранилище в памяти и локальный хранилище. Он также заполняет запас поддельными данными, которые автоматически создаются с помощью пакета NuGet Bogus . Все это намеренно для демонстрации функциональности.

Развертывание в службе приложений Azure

Типичное приложение Orleans состоит из кластера серверных процессов (разрозненных), где живут объекты grain, и набора клиентских процессов, обычно веб-серверов, которые получают внешние запросы, преобразовывают их в вызовы методов grain и возвращают результаты. Следовательно, первое, что нужно сделать для запуска приложения Orleans, — это запустить кластер разрозненности. В целях тестирования кластер может состоять из одного бункера.

Примечание

Для надежного развертывания в рабочей среде требуется несколько разрознов в кластере для отказоустойчивости и масштабирования.

Перед развертыванием приложения необходимо создать группу ресурсов Azure (или использовать существующую). Чтобы создать группу ресурсов Azure, воспользуйтесь одной из следующих статей:

Запишите выбранное имя группы ресурсов. Оно понадобится позже для развертывания приложения.

Создание субъекта-службы

Чтобы автоматизировать развертывание приложения, необходимо создать субъект-службу. Это учетная запись Майкрософт, которая имеет разрешение на управление ресурсами Azure от вашего имени.

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

Созданные учетные данные JSON будут выглядеть примерно так, но с фактическими значениями для клиента, подписки и клиента:

{
  "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"
}

Скопируйте выходные данные команды в буфер обмена и перейдите к следующему шагу.

Создание секрета GitHub

GitHub предоставляет механизм создания зашифрованных секретов. Создаваемые секреты доступны для использования в GitHub Actions рабочих процессах. Вы узнаете, как GitHub Actions можно использовать для автоматизации развертывания приложения в сочетании с Azure Bicep. Bicep — это язык, зависящий от предметной области (DSL), который использует декларативный синтаксис для развертывания ресурсов Azure. Дополнительные сведения см. в разделе Что такое Bicep. Используя выходные данные шага Создание субъекта-службы , необходимо создать секрет GitHub с учетными AZURE_CREDENTIALS данными в формате JSON.

В репозитории GitHub выберите Параметры Секреты>>Создать новый секрет. Введите имя AZURE_CREDENTIALS и вставьте учетные данные JSON из предыдущего шага в поле Значение .

Репозиторий GitHub: Параметры Секреты >

Дополнительные сведения см. в разделе GitHub: Зашифрованные секреты.

Подготовка к развертыванию Azure

Приложение необходимо упаковать для развертывания. В проекте мы определяем Orleans.ShoppingCart.SilosTarget элемент, который выполняется после Publish шага. Каталог публикации запакуется в zip-файлsilo.zip :

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

Существует множество способов развертывания приложения .NET для Служба приложений Azure. В этом руководстве используются GitHub Actions, Azure Bicep, а также .NET и azure CLIs. Рассмотрим файл ./github/workflows/deploy.yml в корне репозитория GitHub:

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

Предыдущий рабочий процесс GitHub:

  • Опубликуйте приложение корзины покупок в виде ZIP-файла с помощью команды dotnet publish .
  • Войдите в Azure, используя учетные данные из шага Создание субъекта-службы .
  • Оцените файл main.bicep и запустите группу развертывания с помощью команды az deployment group create.
  • Разверните файлsilo.zip в Служба приложений Azure с помощью команды az webapp deploy.
    • Также настраивается дополнительное развертывание для промежуточного хранения.

Рабочий процесс запускается принудительной отправкой в ветвь main. Дополнительные сведения см. в разделе GitHub Actions и .NET.

Совет

При возникновении проблем при выполнении рабочего процесса может потребоваться убедиться, что субъект-служба имеет все необходимые пространства имен поставщиков, зарегистрированные. Требуются следующие пространства имен поставщика:

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

Дополнительные сведения см. в статье Устранение ошибок при регистрации поставщика ресурсов.

Azure накладывает ограничения на именование и соглашения для ресурсов. Необходимо обновить значения файла deploy.yml для следующих значений:

  • UNIQUE_APP_NAME
  • AZURE_RESOURCE_GROUP_NAME
  • AZURE_RESOURCE_GROUP_LOCATION

Задайте для этих значений уникальное имя приложения, а также имя и расположение группы ресурсов Azure.

Дополнительные сведения см. в статье Правила и ограничения именования для ресурсов Azure.

Изучение шаблонов Bicep

При выполнении az deployment group create команды она будет оценивать файл main.bicep. Этот файл содержит ресурсы Azure, которые требуется развернуть. Один из способов подумать об этом шаге заключается в том, что он подготавливает все ресурсы для развертывания.

Важно!

Если вы используете Visual Studio Code, то при использовании расширения Bicep улучшается процесс разработки bicep.

Существует много файлов Bicep, каждый из которых содержит ресурсы или модули (коллекции ресурсов). Файл main.bicep является точкой входа и состоит в основном из определенийmodule:

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
  }
}

Предыдущий файл bicep определяет следующее:

  • Два параметра для имени группы ресурсов и имени приложения.
  • Определение storageModule , определяющее учетную запись хранения.
  • Определение logsModule , определяющее ресурсы Azure Log Analytics и Application Insights.
  • Ресурс vnet , определяющий виртуальную сеть.
  • ОпределениеsiloModule, определяющее Служба приложений Azure.

Одним из очень важных resource является то, что виртуальная сеть. Ресурс vnet позволяет Служба приложений Azure взаимодействовать с кластером Orleans.

Всякий module раз, когда обнаруживается в файле bicep, он вычисляется с помощью другого файла bicep, содержащего определения ресурсов. Первым модулем был storageModuleмодуль , который определен в файле 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 принимают параметры, которые объявляются с помощью param ключевое слово. Аналогичным образом, они также могут объявлять выходные output данные с помощью ключевое слово. Хранилище resource зависит от Microsoft.Storage/storageAccounts@2021-08-01 типа и версии. Он будет подготовлен в расположении группы ресурсов в виде StorageV2 номера SKU и Standard_LRS . Bicep хранилища определяет строку подключения в виде output. Позже connectionString он используется silo bicep для подключения к учетной записи хранения.

Затем в файле logs-and-insights.bicep определяются ресурсы Azure Log Analytics и 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

Этот файл bicep определяет ресурсы Azure Log Analytics и Application Insights. Ресурс appInsights является типом web , а logs ресурс — типом PerGB2018 . appInsights И ресурс, logs и ресурс подготавливаются в расположении группы ресурсов. Ресурс appInsights связан с ресурсом logs с помощью WorkspaceResourceId свойства . В этом bicep определены два выходных данных, которые затем используются Служба приложений module.

Наконец, файл app-service.bicep определяет ресурс Служба приложений Azure:

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'
  }
}

Этот файл bicep настраивает Служба приложений Azure как приложение .NET 7. appServicePlan И ресурс, appService и ресурс подготавливаются в расположении группы ресурсов. Ресурс appService настроен для использования S1 номера SKU с емкостью 1. Кроме того, ресурс настроен для использования подсети vnetSubnetId и https. Он также настраивает appInsightsInstrumentationKey ключ инструментирования, appInsightsConnectionString строку подключения и storageConnectionString строку подключения. Они используются приложением корзины для покупок.

Упомянутое выше расширение Visual Studio Code для Bicep включает визуализатор. Все эти файлы bicep визуализированы следующим образом:

Orleans: пример приложения bicep подготовки визуализатор отрисовки корзины для покупок.

Промежуточные среды

Инфраструктура развертывания может развертываться в промежуточных средах, которые являются кратковременными, ориентированными на тестирование и неизменяемыми бросковыми средами. Эти среды очень полезны для тестирования развертываний перед их продвижением в рабочую среду.

Примечание

Если ваша Служба приложений работает в Windows, каждый Служба приложений должен находиться в отдельном плане Служба приложений. Кроме того, чтобы избежать такой конфигурации, можно использовать Служба приложений в Linux, и эта проблема будет решена.

Итоги

При обновлении исходного кода и push изменениях в main ветви репозитория будет выполняться рабочий процесс deploy.yml . Он предоставит ресурсы, определенные в файлах bicep, и развернет приложение. Приложение можно расширить для включения новых функций, таких как проверка подлинности, или для поддержки нескольких экземпляров приложения. Основная цель этого рабочего процесса — продемонстрировать возможность подготовки и развертывания ресурсов за один шаг.

В дополнение к визуализатору из расширения bicep страница группы ресурсов портал Azure будет выглядеть примерно так, как в следующем примере после подготовки и развертывания приложения:

Портал Azure: примеры ресурсов приложения для корзины для покупок в Orleans.

См. также раздел