Руководство. Использование динамической конфигурации с помощью принудительного обновления в приложении .NET

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

  1. Модель опроса: это поведение по умолчанию, которое использует опрос для обнаружения изменений в конфигурации. Когда истекает срок действия кэшированного значения параметра, при следующем вызове к TryRefreshAsync или RefreshAsync отправляется запрос на сервер, чтобы проверить, изменилась ли конфигурация. При необходимости извлекается обновленная конфигурация.

  2. Модель отправки: это использует события Конфигурация приложений для обнаружения изменений в конфигурации. Когда Конфигурация приложений будет настроена для отправки событий изменения значения ключа в Сетку событий Azure, с их помощью приложение сможет оптимизировать общее число запросов, необходимых для обновления конфигурации. Приложения могут подписываться на события напрямую из Сетки событий либо с помощью одного из поддерживаемых обработчиков событий, таких как веб-перехватчик, функция Azure либо раздел Служебной шины.

Из этого руководства вы узнаете, как реализовать динамические обновления конфигурации в коде путем обновления в режиме отправки. При этом в качестве основы используется код приложения, представленный в руководстве. Прежде чем продолжить, завершите руководство . Сначала используйте динамическую конфигурацию в приложении .NET.

Вы можете выполнять шаги в этом учебнике с помощью любого редактора кода. Visual Studio Code является отличным вариантом, который доступен на платформах Windows, macOS и Linux.

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

  • настройка подписки на отправку событий изменения конфигурации из Конфигурации приложений в раздел Служебной шины;
  • Настройте приложение .NET для обновления конфигурации в ответ на изменения в Конфигурация приложений.
  • использование последней конфигурации в приложении.

Необходимые компоненты

Настройка раздела и подписки Служебной шины Azure

Для работы с этим руководством используется интеграция Служебной шины для Сетки событий, чтобы упростить обнаружение изменений конфигурации для приложений, которые не могут опрашивать Конфигурацию приложений на предмет изменений. Пакет SDK для Служебной шины Azure предоставляет API для регистрации обработчика сообщений, с помощью которого можно обновлять конфигурацию при обнаружении изменений в Конфигурации приложений. Выполните шаги из краткого руководства по созданию раздела и подписки Служебной шины с помощью портала Azure, чтобы создать пространство имен, раздел и подписку Служебной шины.

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

Ключ Значение
ServiceBusConnectionString Строка подключения к пространству имен Служебной шины
ServiceBusTopic Имя раздела Служебной шины
ServiceBusSubscription Имя подписки Служебной шины

Настройка подписки на события

  1. Откройте ресурс Конфигурации приложений на портале Azure, а затем щелкните + Event Subscription в области Events.

    События Конфигурации приложений

  2. Введите имена для Event Subscription и System Topic.

    Создание подписки на события

  3. Выберите для Endpoint Type значение Service Bus Topic, выберите раздел Служебной шины, а затем щелкните Confirm Selection.

    Конечная точка Служебной шины для подписки на события

  4. Щелкните Create, чтобы добавить подписку на событие.

  5. Нажмите Event Subscriptions в области Events, чтобы проверить, создана ли подписка.

    Подписки на события Конфигурации приложений

Примечание.

При подписке на изменения конфигурации можно использовать один или несколько фильтров. Они позволяют сократить число событий, отправляемых в приложение. Такие фильтры можно настроить как фильтры подписки Сетки событий или фильтры подписки Служебной шины. Например, с помощью фильтра можно подписаться только на события изменений в ключе, который начинается с определенной строки.

Регистрация обработчика событий для повторной загрузки данных из Конфигурации приложений

Откройте файл Program.cs и замените код в нем следующим:

using Azure.Messaging.EventGrid;
using Azure.Messaging.ServiceBus;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
using Microsoft.Extensions.Configuration.AzureAppConfiguration.Extensions;
using System;
using System.Threading.Tasks;

namespace TestConsole
{
    class Program
    {
        private const string AppConfigurationConnectionStringEnvVarName = "AppConfigurationConnectionString";
        // e.g. Endpoint=https://{store_name}.azconfig.io;Id={id};Secret={secret}
        
        private const string ServiceBusConnectionStringEnvVarName = "ServiceBusConnectionString";
        // e.g. Endpoint=sb://{service_bus_name}.servicebus.windows.net/;SharedAccessKeyName={key_name};SharedAccessKey={key}
        
        private const string ServiceBusTopicEnvVarName = "ServiceBusTopic";
        private const string ServiceBusSubscriptionEnvVarName = "ServiceBusSubscription";

        private static IConfigurationRefresher _refresher = null;

        static async Task Main(string[] args)
        {
            string appConfigurationConnectionString = Environment.GetEnvironmentVariable(AppConfigurationConnectionStringEnvVarName);

            IConfiguration configuration = new ConfigurationBuilder()
                .AddAzureAppConfiguration(options =>
                {
                    options.Connect(appConfigurationConnectionString);
                    options.ConfigureRefresh(refresh =>
                        refresh
                            .Register("TestApp:Settings:Message")
                            .SetCacheExpiration(TimeSpan.FromDays(1))  // Important: Reduce poll frequency
                    );

                    _refresher = options.GetRefresher();
                }).Build();

            RegisterRefreshEventHandler();
            var message = configuration["TestApp:Settings:Message"];
            Console.WriteLine($"Initial value: {configuration["TestApp:Settings:Message"]}");

            while (true)
            {
                await _refresher.TryRefreshAsync();

                if (configuration["TestApp:Settings:Message"] != message)
                {
                    Console.WriteLine($"New value: {configuration["TestApp:Settings:Message"]}");
                    message = configuration["TestApp:Settings:Message"];
                }

                await Task.Delay(TimeSpan.FromSeconds(1));
            }
        }

        private static void RegisterRefreshEventHandler()
        {
            string serviceBusConnectionString = Environment.GetEnvironmentVariable(ServiceBusConnectionStringEnvVarName);
            string serviceBusTopic = Environment.GetEnvironmentVariable(ServiceBusTopicEnvVarName);
            string serviceBusSubscription = Environment.GetEnvironmentVariable(ServiceBusSubscriptionEnvVarName);
            ServiceBusClient serviceBusClient = new ServiceBusClient(serviceBusConnectionString);
            ServiceBusProcessor serviceBusProcessor = serviceBusClient.CreateProcessor(serviceBusTopic, serviceBusSubscription);

            serviceBusProcessor.ProcessMessageAsync += (processMessageEventArgs) =>
                {
                    // Build EventGridEvent from notification message
                    EventGridEvent eventGridEvent = EventGridEvent.Parse(BinaryData.FromBytes(processMessageEventArgs.Message.Body));

                    // Create PushNotification from eventGridEvent
                    eventGridEvent.TryCreatePushNotification(out PushNotification pushNotification);

                    // Prompt Configuration Refresh based on the PushNotification
                    _refresher.ProcessPushNotification(pushNotification);

                    return Task.CompletedTask;
                };

            serviceBusProcessor.ProcessErrorAsync += (exceptionargs) =>
                {
                    Console.WriteLine($"{exceptionargs.Exception}");
                    return Task.CompletedTask;
                };
        }
    }
}

Метод ProcessPushNotification сбрасывает срок действия кэша до короткой случайной задержки. Это приводит к тому, что будущие вызовы RefreshAsync или TryRefreshAsync повторно проверяют кэшированные значения в конфигурации приложения и при необходимости обновляют их. В этом примере вы регистрируетесь для отслеживания изменений в ключе: TestApp:Settings:Message с истечением срока действия кэша, равным одному дню. Это означает, что ни один запрос к конфигурации приложения не будет выполнен до окончания дня после последней проверки. При вызове ProcessPushNotification приложение направит запросы к конфигурации приложения в течение нескольких секунд. Приложение будет загружать новые значения конфигурации вскоре после внесения изменений в хранилище App Configuration без необходимости постоянного опроса обновлений. Если ваше приложение по какой-либо причине пропустило уведомление об изменении, оно по-прежнему будет проверять изменения конфигурации раз в день.

Короткая случайная задержка для истечения срока действия кэша полезна при наличии большого числа экземпляров приложения или микрослужб, подключающихся к одному хранилищу конфигурации приложений с моделью push-уведомлений. Без этой задержки все экземпляры приложения могут отправлять запросы в хранилище конфигураций приложений одновременно, как только они получат уведомление об изменении. Это может привести к регулированию хранилища службой настройки приложения. Задержка истечения срока действия кэша равна случайному числу от 0 до 30 секунд по умолчанию, но максимальное значение можно изменить с помощью необязательного параметра maxDelay для метода ProcessPushNotification.

Метод ProcessPushNotification принимает объектPushNotification, содержащий сведения о том, какое изменение в Конфигурация приложений активировало push-уведомление. Это помогает обеспечить загрузку всех изменений конфигурации, включая событие, вызвавшее срабатывание, в следующее обновление конфигурации. Метод SetDirty не гарантирует, что изменение, которое активирует отправку push-уведомления в немедленное обновление конфигурации. Если вы используете метод SetDirty для модели push-уведомлений, рекомендуется использовать вместо него метод ProcessPushNotification.

Создание и запуск приложения локально

  1. Задайте переменную среды с именем AppConfigurationConnectionString и присвойте ей значение ключа доступа к хранилищу Конфигурации приложений.

    Для сборки и запуска приложения локально с помощью командной строки Windows выполните следующую команду и перезапустите командную строку, чтобы изменения вступили в силу:

    setx AppConfigurationConnectionString "connection-string-of-your-app-configuration-store"
    
  2. Чтобы создать консольное приложение, выполните следующую команду:

    dotnet build
    
  3. Когда создание завершится, запустите приложение локально с помощью следующей команды:

    dotnet run
    

    Запуск режима отправки перед обновлением

  4. Войдите на портал Azure. Щелкните Все ресурсы и выберите экземпляр хранилища Конфигурации приложений, который вы создали по инструкциям из краткого руководства.

  5. Выберите Configuration Explorer (Обозреватель конфигураций) и измените значения следующих ключей.

    Ключ Значение
    TestApp:Settings:FontSize Данные из конфигурации приложений Azure. Обновлено
  6. Подождите несколько минут, чтобы разрешить обработку события. Вы увидите обновленную конфигурацию.

    Запуск режима отправки после обновления

Очистка ресурсов

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

Внимание

Удаление группы ресурсов — процесс необратимый. Группа ресурсов и все содержащиеся в ней ресурсы удаляются без возможности восстановления. Будьте внимательны, чтобы случайно не удалить не те ресурсы или группу ресурсов. Если ресурсы для работы с этой статьей созданы в группе ресурсов, которая содержит другие нужные ресурсы, удалите каждый ресурс отдельно в соответствующей области ресурса, чтобы не удалять группу ресурсов.

  1. Войдите на портал Azure и выберитеГруппы ресурсов.
  2. Введите имя группы ресурсов в поле Фильтровать по имени.
  3. В списке результатов выберите имя группы ресурсов, чтобы просмотреть общие сведения.
  4. Выберите команду Удалить группу ресурсов.
  5. Подтвердите операцию удаления группы ресурсов. Введите имя группы ресурсов, которую необходимо удалить, и нажмите Удалить.

Через некоторое время группа ресурсов и все ее ресурсы будут удалены.

Следующие шаги

В этом руководстве вы включили приложение .NET для динамического обновления параметров конфигурации из Конфигурация приложений. Чтобы узнать, как с помощью удостоверения, управляемого Azure, упростить доступ к службе "Конфигурация приложений Azure", перейдите к следующему учебнику.