Упражнение. Реализация устойчивости приложений

Завершено

В проекте eShop есть две службы, которые взаимодействуют друг с другом с помощью HTTP-запросов. Служба Store вызывает Product службу, чтобы получить список всех текущих продуктов, доступных для покупки.

Текущая версия приложения не имеет обработки устойчивости. Product Если служба недоступна, Store служба возвращает клиенту ошибку и просит их повторить попытку позже. Это поведение не является хорошим взаимодействием с пользователем.

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

В этом упражнении вы добавите устойчивость к существующему облачному приложению и протестируете исправление.

Открытие среды разработки

Вы можете использовать пространство кода GitHub, в котором размещено упражнение, или выполнить упражнение локально в Visual Studio Code.

Чтобы использовать пространство кода, создайте предварительно настроенное пространство GitHub Codespace с помощью этой ссылки на создание Codespace.

GitHub занимает несколько минут, чтобы создать и настроить пространство кода. По завершении процесса вы увидите файлы кода для упражнения. Код, используемый для остальной части этого модуля, находится в каталоге /dotnet-resiliency .

Чтобы использовать Visual Studio Code, клонируйте репозиторий https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative на локальный компьютер. Затем:

  1. Установите все системные реквименты для запуска контейнера разработки в Visual Studio Code.
  2. Убедитесь, что Docker запущен.
  3. В новом окне Visual Studio Code откройте папку клонированного репозитория
  4. Нажмите клавиши CTRL SHIFT++P, чтобы открыть палитру команд.
  5. Поиск: контейнеры разработки: >перестроение и повторное открытие в контейнере
  6. Выберите eShopLite — dotnet-устойчивость из раскрывающегося списка. Visual Studio Code создает контейнер разработки локально.

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

  1. На нижней панели перейдите на вкладку ТЕРМИНАЛА и выполните следующую команду в корневой каталог кода:

    cd dotnet-resiliency
    
  2. Выполните следующую команду, чтобы создать образы приложений eShop:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. После завершения сборки выполните следующую команду, чтобы запустить приложение:

    docker compose up
    
  4. На нижней панели выберите вкладку "ПОРТЫ ", а затем в столбце "Пересылаемый адрес" таблицы щелкните значок "Открыть в браузере " для порта переднего плана (32000).

    Если приложение запущено локально, откройте окно браузера для просмотра http://localhost:32000/products.

  5. Приложение eShop должно работать. Выберите пункт меню "Продукты", вы увидите список продуктов.

    Снимок экрана: приложение eShop, работающее в браузере.

Проверка текущей устойчивости

Остановите службу продуктов, чтобы узнать, что происходит с приложением.

  1. Вернитесь к пространству кода и на вкладке терминала выберите + , чтобы открыть новый терминал Bash.

  2. Выполните следующую команду Docker, чтобы получить список запущенных контейнеров:

    docker ps
    

    Вы увидите список запущенных в настоящее время контейнеров, например:

    CONTAINER ID   IMAGE                                                                            COMMAND                  CREATED          STATUS          PORTS                                                        NAMES
    c08285e8aaa4   storeimage                                                                       "dotnet Store.dll"       8 minutes ago    Up 8 minutes    80/tcp, 443/tcp, 0.0.0.0:5902->8080/tcp, :::5902->8080/tcp   eshoplite-frontend-1
    6ba80f3c7ab0   productservice                                                                   "dotnet Products.dll"    8 minutes ago    Up 8 minutes    80/tcp, 443/tcp, 0.0.0.0:5200->8080/tcp, :::5200->8080/tcp   eshoplite-backend-1
    cd0c822a5222   vsc-eshoplite-958868d22c9851dd911b2423199bfc782861d1a8f7afac48e5096a1b7516082f   "/bin/sh -c 'echo Co…"   27 minutes ago   Up 27 minutes     
    
  3. Найдите идентификатор КОНТЕЙНЕРА для контейнера productservice . В приведенном выше примере идентификатор равен 6ba80f3c7ab0.

  4. Остановите службу продуктов с помощью этой команды Docker:

    docker stop <CONTAINER ID>
    

    <CONTAINER ID> Где находится идентификатор, найденный на предыдущем шаге. Например:

    docker stop 6ba80f3c7ab0
    
  5. Вернитесь на вкладку браузера, на котором запущено приложение, и обновите страницу. Должно появиться сообщение об ошибке:

    Возникла проблема с загрузкой наших продуктов. Повторите попытку позже.

  6. Вернитесь к пространству кода и в терминале выберите терминал Docker и нажмите клавиши CTRL+C, чтобы остановить приложение. Должно отображаться следующее:

    Gracefully stopping... (press Ctrl+C again to force)
    Aborting on container exit...
    [+] Stopping 2/1
     ✔ Container eshoplite-frontend-1  Stopped                                                                      0.3s 
     ✔ Container eshoplite-backend-1   Stopped                                                                      0.0s 
    canceled
    

Добавление устойчивости к приложению

Для повышения устойчивости приложения необходимо добавить Microsoft.Extensions.Http.Resilience пакет NuGet в проект. Затем его можно использовать в Program.cs.

Добавление пакета Microsoft.Extensions.Http.Resilience

  1. В пространстве кода на вкладке ТЕРМИНАЛА перейдите в папку проекта Store :

    cd Store
    
  2. Выполните следующую команду, чтобы добавить пакет NuGet для устойчивости:

    dotnet add package Microsoft.Extensions.Http.Resilience
    

    Выполнение этой команды из терминала в папке проекта приложений добавляет ссылку на пакет в файл проекта Store.csproj .

  3. На боковой панели обозревателя выберите Program.cs.

  4. Добавьте следующую инструкцию using в начало файла:

    using Microsoft.Extensions.Http.Resilience;
    

Добавление стандартной стратегии устойчивости

  1. В строке 13 добавьте следующий код:

    .AddStandardResilienceHandler()
    

    Код должен выглядеть следующим образом:

    builder.Services.AddHttpClient<ProductService>(c =>
    {
        var url = builder.Configuration["ProductEndpoint"] ?? throw new InvalidOperationException("ProductEndpoint is not set");
    
        c.BaseAddress = new(url);
    }).AddStandardResilienceHandler();
    

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

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

  2. Выполните следующие команды, чтобы перестроить приложение eShop:

    cd ..
    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. После завершения сборки выполните следующую команду, чтобы запустить приложение:

    docker compose up
    
  4. Вернитесь на вкладку браузера, на котором запущено приложение, и обновите страницу продукта. Вы увидите список продуктов.

  5. Вернитесь к пространству кода и на вкладке ТЕРМИНАЛА выберите второй терминал Bash. Скопируйте идентификатор КОНТЕЙНЕРА для контейнера productservice .

  6. Повторно выполните команду docker stop:

    docker stop <CONTAINER ID>
    
  7. Вернитесь на вкладку браузера, на котором запущено приложение, и обновите страницу продукта. На этот раз оно должно занять некоторое время, пока не увидите сообщение об ошибке приложений:

    Возникла проблема с загрузкой наших продуктов. Повторите попытку позже.

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

  8. Вернитесь к пространству кода и на вкладке ТЕРМИНАЛА выберите терминал Docker.

  9. В терминале нажмите клавиши CTRL+C, чтобы остановить работу приложения.

  10. В сообщениях журнала прокрутите страницу вверх, пока не найдете ссылки на Polly.

    eshoplite-frontend-1  | warn: Polly[3]
    eshoplite-frontend-1  |       Execution attempt. Source: 'ProductService-standard//Standard-Retry', Operation Key: '', Result: 'Name or service not known (backend:8080)', Handled: 'True', Attempt: '2', Execution Time: '27.2703'
    

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

Настройка стратегии устойчивости

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

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

  1. В окне кода для Program.cs измените код в строке 13 следующим образом:

    .AddStandardResilienceHandler(options =>
    {
        options.Retry.MaxRetryAttempts = 7;
    });
    

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

  2. Остановите docker вверх с помощью ctrl+C. Затем выполните следующую команду, чтобы перестроить приложение eShop:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. После завершения сборки выполните следующую команду, чтобы запустить приложение:

    docker compose up
    

    Остановите контейнер серверной службы в терминале Bash и обновите eShop. Обратите внимание, что сообщение об ошибке занимает больше времени. Если вы проверка журналы, но вы можете увидеть, что стратегия повторных попыток только в пять раз. Последнее сообщение из Polly:

    Polly.Timeout.TimeoutRejectedException: The operation didn't complete within the allowed timeout of '00:00:30'.
    

    В приведенном выше сообщении показано, что общее время ожидания запроса останавливает максимальное количество повторных попыток. Вы можете устранить проблему, увеличив общее время ожидания запроса.

  4. В терминале нажмите клавиши CTRL+C, чтобы остановить приложение.

  5. В окне кода для Program.cs измените код в строке 13 следующим образом:

    .AddStandardResilienceHandler(options =>
    {
        options.Retry.RetryCount = 7;
        options.TotalRequestTimeout = new HttpTimeoutStrategyOptions
        {
            Timeout = TimeSpan.FromMinutes(5)
        };
    });
    

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

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

  6. Выполните следующую команду, чтобы перестроить приложение eShop:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  7. После завершения сборки выполните следующую команду, чтобы запустить приложение:

    docker compose up
    

Тестирование новых параметров устойчивости

Чтобы протестировать приложение в контейнере, используйте расширение Docker. Расширение предоставляет графический интерфейс для просмотра и управления состоянием контейнеров.

  1. В меню слева выберите значок Docker .

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

  2. На панели DOCKER в разделе "КОНТЕЙНЕРЫ" щелкните правой кнопкой мыши контейнер продуктов и выберите "Остановить".

  3. Вернитесь на вкладку браузера, на котором запущено приложение, и обновите страницу продукта. Должно появиться сообщение "Загрузка... ".

  4. Вернитесь к пространству кода и на вкладке ТЕРМИНАЛА выберите терминал Docker. Стратегия устойчивости работает.

  5. На панели DOCKER в разделе "КОНТЕЙНЕРЫ" щелкните правой кнопкой мыши контейнер продуктов и выберите "Пуск".

  6. Вернитесь на вкладку браузера, на котором запущено приложение. Подождите и приложение должно восстановить список продуктов.

  7. В терминале остановите docker с помощью ctrl+C.