- PVSM.RU - https://www.pvsm.ru -

Найдена формула безболезненного перехода на .Net Core

На все про все достаточно 50 чашек кофе.

Помимо обозначенного выше эмпирического правила мы публикуем краткую заметку о моментах, на которые нужно обратить пристальное внимание, чтобы на бою и в процессах ничего не сломалось. Заметку составили по горячим следам релиза мобильного сервиса, совсем мигрировавшего на .Net Сore (начало было положено тут [1]). Нам удалось выполнить эту операцию незаметно для заказчика, почти не останавливая основной процесс разработки.

Ниже будет готовый план действий, будет очень емкий тест-лист, будет вот эта картинка для настроения:

Найдена формула безболезненного перехода на .Net Core - 1

Итак, по шагам:

1. Запланировать длинный спринт с большими фичами и/или регрессом

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

2. В аккурат к спринту переписать код на .Net Core

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

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

  • По возможности в используемых сервисах переписать WCF интерфейсы на webapi

Реализация .Net Core WCF-клиента все еще далека от идеала. Несмотря на то, что старые болячки [2] в каком-то смысле пофикшены, в новых версиях все равно приходится использовать workaround (1 [3], 2 [4]).

Для истории: на .Net Core 2.0 стабильной рабочей версией WCF является 4.4.2 из myget репозитория. У нее, например, нет проблем с досрочным таймаутом

В момент начала миграции мы использовали версию .Net Core 2.0. Тем временем Microsoft релизнула .Net Core 2.1. Кому интересно полюбоваться успехами ребят из Редмонда в оптимизации платформы, просим почитать, какого прогресса добился поисковик Bing [5] при апгрейде на новую версию (спойлер: латенси упало на 34%!)

Мы тоже обновились до .Net Core 2.1 и WCF 4.5.3. И не забыли в Dockerfile указать свежий базовый образ microsoft/dotnet:2.1-aspnetcore-runtime. Каково было удивление, когда вместо 1.4Гб увидели размер образа в 0,5Гб (речь про Windows-образ, если вдруг).

3. Задеплоить на тест и демо

У нас в распоряжении два окружения. Демо мы оставили со старой версией как эталон. На тестовое окружение задеплоили новый сервис — обкатать на разработчиках и тестировщиках.

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

  • Настроить IIS

Для запуска .Net Core сервиса в IIS необходимо установить модуль [6], который идет в комплекте с рантаймом.

AppPool переключаем на CLR Runtime = No Managed Code.

В солюшене в стандартном web.config [7] важно не забыть выставить нужный requestTimeout и отключить WebDAV модуль, если есть DELETE-методы.

Далее, для публикации сервиса в IIS есть два варианта:

  • вы делаете MSDeploy sync — значит дополнительно нужен ключ [8] -enableRule:AppOffline
  • вы делает file publish — значит ровно перед публикацией нужно подложить файлик app_offline.htm в директорию сервиса, а после публикации удалить его

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

Мы отказались от логирования через Nlog в пользу Serilog, и потеряли автоматическое сжатие логов — в Serilog такой фичи просто нет. В этом случае можно спастись штатными средствами Windows и в свойствах директории установить NTFS compression.

4. Протестировать

Вот максимально ужатый чеклист по самым хрупким местам:

  • проверить возврат статус-кодов Bad request, Unauthorized, Not modified, Not found — все, что API может отдать
  • проверить логирование запросов для всех статус-кодов
  • составить схему внешних зависимостей; как правило вся необходимая информация есть в appsettings
    • прогнать методы, которые затрагивают их работу
    • проверить логирование внешних запросов
  • проверить функционирование настроек для параметров appsettings; попробовать поменять их на горячую
  • проверить http-кэширование для положительных и отрицательных статус-кодов
    • хедер ETag
    • хедер Сache-Сontrol
  • проверить длительные запросы и таймауты
  • проверить запросы с пустым ответом
  • проверить DELETE-методы (WebDAV отключен или нет)
  • проверить работу с raw content
    • заливка и выгрузка одного/нескольких файлов
    • заливка файлов с размером выше лимита
    • простановка хедера Content-Disposition
  • проверить все остальные хедеры; собрать их все в кучу по коду довольно легко
  • проверить условное выполнение кода при переключении окружений if (env.IsDevelopment())
  • проверить разрыв соединения с клиента и на сервере
  • сравнить с эталоном swagger.json — поможет обнаружить разницу в передаваемых полях

    У нас в мобильном приложении используется кодогенератор для работы с API на базе описания swagger.json, поэтому было важно, чтобы отличие от исходного описания было минимальным. В последней версии Swashbuckle.AspNetCore сильно поменялся интерфейс и генерируемый swagger.json. Пришлось откатиться на ветхую версию Swashbuckle.AspNetCore 1.2.0 и дописать пару фильтров.

5. Задеплоить на бой, попивая кофеек

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

Таким образом мы получили возможность в случае ЧП быстро переключиться на старую версию.

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

Промежуточный итог

Теперь наш сервис полностью готов обрасти docker-контейнером для поставки в кластер. Мы готовы к деплою и в Kubernetes, и в Service Fabric.

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

Автор: eastbanctech

Источник [9]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/net/291681

Ссылки в тексте:

[1] тут: https://habr.com/company/eastbanctech/blog/348590/

[2] болячки: https://habr.com/company/eastbanctech/blog/350054/

[3] 1: https://github.com/dotnet/wcf/issues/2641

[4] 2: https://github.com/dotnet/wcf/issues/2923

[5] Bing: https://blogs.msdn.microsoft.com/dotnet/2018/08/20/bing-com-runs-on-net-core-2-1/?utm_source=vs_developer_news&utm_medium=referral

[6] модуль: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/?tabs=aspnetcore2x&view=aspnetcore-2.1#install-the-net-core-hosting-bundle

[7] web.config: https://docs.microsoft.com/ru-ru/aspnet/core/host-and-deploy/iis/?view=aspnetcore-2.1&tabs=aspnetcore2x#sub-application-configuration

[8] ключ: https://docs.microsoft.com/en-us/iis/publish/deploying-application-packages/taking-an-application-offline-before-publishing

[9] Источник: https://habr.com/post/422441/?utm_campaign=422441