От легаси к Service Fabric за 360 часов. История одной миграции

Статья посвящена бесконечной борьбе с legacy. Это история о том, что можно сделать, если взять двух разработчиков (второй — для код-ревью) и 360 часов. А также о том, как перенести легаси-код в модный и молодежный клауд-сервис. Код с пошаговой инструкцией тут. Это репозиторий с примером переноса .NET Core Web API как stateless-сервиса Azure Service Fabric c секьюрити, API versioning и т. п.

Начало

Customer: We need to add a new feature to the legacy system, can you give an estimate?
Developer: It depends on when the legacy system will be replaced?
Customer: In five months.
Developer: Then the new feature will take six :)

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

У меня процесс стартовал с обсуждения возможности масштабирования части платформы и уменьшения latency-запросов. Проблемная часть системы была построена на старых сервисах Windows Communication Foundation с классической трехслойной архитектурой. WCF-фреймворк — это SOAP-монстр, но надежный и с широким функционалом, в 2010 году он был основой для Enterprise-решений. На этом же этапе поддержка сервисов и DevOps-задачи забирали приличный объем времени.

Оптимальным считается подход Lift and Shift, который подразумевает перенос сервисов в облако на виртуальные машины с дальнейшим постепенным разделением и рефакторингом на отдельные компоненты. Но такой подход не входил в мои планы, хотя на первый взгляд физически и экономически он выглядел вполне разумно. С другой стороны, перенос кода на .NET Core Web API было достаточно сложно оценить. В результате я сделал PoC за несколько выходных, чтобы оценить возможные риски. Конечно же, оценку рисков стоит начать с проверки качества текущего кода, проверить, живы ли Unit-тесты и т. п. Важно также не планировать отпуск, пока миграция не завершилась успешным развертыванием :)

Почему Service Fabric, а не Kubernetes

Focus on development, not on the infrastructure

Одной из проблем при переходе на новые фреймворки и технологии является повышение сложности систем. Связка Kubernetes + Docker буквально означала, что в результате я получу такой объем DevOps-задач, как и при работе с WCF-сервисами, развернутыми на VMware-фермах.

Эффект IKEA — это когнитивное искажение, которое появляется, когда покупатели непропорционально высоко оценивают значимость (ценность) товаров, которые они создают отчасти сами (Wikipedia).

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

Одной из моих задач было сокращение объема maintenance и DevOps-активностей, чтобы освободить время на разработку нового функционала. Azure Service Fabric после небольшого PoC полностью удовлетворил этим требованиям, плюс кривая обучения гораздо более пологая в сравнении с Kubernetes.

Почему Azure Service Fabric?

  • Сокращение цикла разработки.
  • Почти полное отсутствие DevOps-задач.
  • Простой деливери с помощью Azure DevOps CI/CD pipelines.
  • Надежный scale-out and scale-in и отказоустойчивость.
  • Простая разработка, кластер ASF запускается на ПК разработчика.

Оценка

Перед оценкой времени на миграцию сначала нужно оценить нагрузку, понять, какие сервисы используются чаще и где наибольшие проблемы с latency и производительностью. Стоит помнить, что легко перенести можно код stateless-приложения, перенос же хранилища данных зависит от многих факторов; но если это MS SQL, то эта задача достаточно тривиальная.

Главное, с чего стоит начать, это с проверки зависимостей и NuGet-пакетов на совместимость с .NET Standard 2.0. Мне повезло, и тут проблем не оказалось.

Что было сделано во время PoC?

  • Проверка зависимостей на совместимость с .NET Standard 2.0.
  • Создание кластера Azure Service Fabric с подходящей конфигурацией VM.
  • Проект с stateless-сервисом Azure Service Fabric.
  • Публикация сервиса в облако и создание нескольких простых нагрузочных тестов с помощью Postman и Loader.io.

Пример создания кластера с помощью CLI из воркшопа для Azure Bootcamp Lviv

Что нужно не забыть при оценке проекта?

  • Использовать данные, полученные на этапе PoC.
  • Добавить время на Infrastructure as Code и настройку CI/CD через Azure DevOps.
  • Об установке дополнительных сертификатов и о работе с Azure Key Vault.
  • Определиться с секьюрити и выбрать Identity-провайдера.
  • Учесть в оценке стоимость работы Dev, Test and Stage энвайронментов.
  • Не забыть о мониторинге (и начать с него).

Если взять за основу месяц, два спринта и количество часов в районе 300, то все получится. Нужно подготовить список преимуществ и проблем, которые будут решены в результате завершения проекта. Упомянуть уменьшение времени (стоимости) будущих изменений и указать на пользу в ближайшем будущем.

Security — это просто и сложно одновременно. Если сервисы используются внутри сети, то необходимо развернуть Azure VNet и Network Security Group для ограничения доступа к сервисам из интернета. Если же подразумевается открытый доступ, то, имхо, оптимальный вариант — это Identity as a Service в виде Azure AD B2C, OAuth 2.0 или самописного решения на Identity Server 4.

Что нужно знать перед работой с сервис-фабрикой

Начать стоит, как всегда, с документации и терминологии, а конкретно — со страницы, посвященной планированию кластера. Сервис-фабрика — мощная штука, но дело в том, что для начала работы нужно совсем немного, а копнуть глубже можно по мере роста нагрузки (или нет). Для начала важно понимать терминологию и две вещи.

Во-первых, нужно знать разницу между The durability tier и The reliability tier и для чего они нужны.

А во-вторых, понимать, что кластеры Azure Service Fabric работают на тех же Virtual Machine Scale Sets (VMSS), которые используются в Azure App Service. Если с VMSS уже опыт был, тогда переход будет легким. Стоит помнить, что выполнять манипуляции с VMSS в Service Fabric надо только после полного уяснения терминов выше.

Кластер ASF

Cluster: A network-connected set of virtual or physical machines into which your microservices are deployed and managed. Clusters can scale to thousands of machines.

Node: A machine or VM that’s part of a cluster is called a node. Each node is assigned a node name (a string). Nodes have characteristics, such as placement properties. Each machine or VM has an auto-start Windows service, FabricHost.exe, that starts running upon boot and then starts two executables: Fabric.exe and FabricGateway.exe. These two executables make up the node.

Сколько нужно нод и машин в VMSS? Для старта я бы использовал 3 ноды. После первых нагрузочных тестов конфигурацию и количество машин в VMSS можно изменить в любую сторону. Протестируйте нагрузку, и если при нужном вам количестве запросов в минуту (например, 1000) задержки ниже 200 мс, то можно оставить как есть.

Primary-нода в Service Fabric кластере выполняет задачи, связанные с оркестрацией кластера, и делит ресурсы вашего приложения с системными сервисами. Поэтому не стоит удалять и делать эксперименты на ней, а также производить операции scale-up и scale-in без предварительных тестов.

Обязательно нужно различать кластеры durability и reliability tiers. Знать ограничения, касающиеся понижения уровня с золотого до серебряного и т. п. Если вы оценили нагрузку на старые WCF-сервисы и выполнили нагрузочное тестирование API, то после настройки VMSS scale-out можно спать спокойно.

Перенос кода

План был достаточно простым.

  • Перенести код из WCF в Web API.
  • Добавить API в stateless ASF-проект.
  • Добавить все секреты и сертификаты в Azure Key Vault.
  • Распределить функционал по нескольким сервисам.
  • Протестировать результат.

Переносим код. Это несложная операция, требующая внимания и покрытия тестами :) Этап начался с переноса WCF-сервисов в контроллеры Web API, используя правило: 1 сервис => 1 контроллер. Компоненты 3-tier-архитектуры легко переносятся в Onion-архитектуру с composition root в Startup.cs (детали вне контекста этой статьи).

После того как перенос кода выполнен, стоит протестировать результат: сделать набор запросов к API и прогнать с помощью Postman. Если HTTP 200, то можно приступать к рефакторингу старых Unit- и Integration-тестов.

Устанавливаем Azure Service Fabric SDK. К сожалению, компоненты локального кластера не работают нормально с Visual Studio 2019, по-прежнему необходима установленная Visual Studio 2017. Перегружаемся и получаем информационное сообщение о запуске локального кластера ASF. После перезагрузки и автоматического запуска кластера стоит сразу уменьшить capacity до 1 ноды, чтобы не тратить ресурсы VM впустую.

Создаем проект Service Fabric с stateless-сервисом для Web, запускаем и переходим по URL созданного контроллера для проверки. Затем заменяем созданное веб-приложение Web API и изменяем GUID проекта в sln-файле. Собираем проект, запускаем и затем проверяем контроллеры с помощью набора запросов в Postman. Вуаля!

Разбиваем сервис на несколько логических частей. Руководствоваться стоит данными по нагрузке, собранными на этапе эстимирования, и здравым (!) смыслом. В описанном выше случае 10 WCF-сервисов поместились в 3 Web-сервиса. Нагрузка при этом оказалась неравномерной, и много ресурсов VMSS (Standard_D1_v2) попросту простаивали. К сожалению, серебряной пули нет и придется проверять нагрузку с помощью нагрузочных тестов. В идеале запускать нагрузочные тесты лучше из Azure DevOps, для этого создать нужное число аккаунтов и использовать бесплатный объем тестов из каждого ;)

К сожалению, к моменту запуска не все тесты в солюшене были переписаны под новое .NET Core приложение :(

Конечно же, были и проблемы

Оказалось, что подход Infrastructure as Code подкинул проблем. При попытке создать кластер фабрики через портал с названиями из скрипта Azure CLI названия не проходят валидацию в инпутах :) Видимо, на портале валидация слегка устаревшая, так как инфраструктурные скрипты продолжают выполняться.

Вывод: не используйте GUI, описывайте вашу инфраструктуру в коде и храните ее в Git или хотя бы в проектной Wiki.

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

Цена кластера из 5 нод будет в районе 500 долларов США в месяц. Чтобы уменьшить цену минимум в 3 раза, нужно использовать Linux-машины с shared compute типа Standard_B2s и контракт на 3 года. Но тут надо трезво оценить свои силы (время), так как проект .NET Core Web API, скорее всего, не запустится сразу под Linux.

Установка сертификатов кластера тоже имеет специфику и лучшим образом выполняется только с помощью PowerShell-скриптов. Внимательно отнеситесь к эстимированию задач по деплойменту ;) И храните секреты (сертификаты) в Azure Key Vault. Но если надо, то ниже скрипт для установки сертификатов в кластере.

Полезно разобраться в том, как работает Load Balancer, каковы принципы работы Reverse Proxy, что такое VNet и почему нужна Network Security Group. Но, строго говоря, для старта достаточно двух действий: добавления Load Balancer порта 443 и health probe для этого порта. И не забыть удалить порт 80 :)

Для администрирования кластера я использую PowerShell и Azure CLI

Заключение

Как показал опыт, инвестиция своего времени окупается в будущем. Миграция прошла практически без проблем, но дальнейшего роста кластера не последовало. Ответом на рост нагрузки стал перенос кода в Serverless-решения.

Что я бы сделал сейчас по-другому? В принципе, многое. Как минимум перенес бы часть нагруженных сервисов на FaaS в виде Azure Functions с увеличением эстимейта. Но это уже совсем другая история. С учетом требований этот проект оправдал себя. Cheers!

Полезные ссылки:


Если будут вопросы, пишите мне в Twitter.

Похожие статьи:
В Интернет попала предварительная информация о готовящихся ноутбуках MacBook Air нового поколения. По сообщению тайваньских источников,...
Я професійно займаюся розробкою програмного забезпечення понад 9 років. За цей час працював і фрилансером, і в продуктових,...
У новому випуску подкасту 1-2-3 Techno поговорили з Юрою Ткаченком про фейли в організації технічних конференцій, впровадження...
Полный выпуск Mobile-Review.com Podcast 304 от 13 октября (1 час 41 минута, 93 МБ, mр3) Люксовые товары. Особое мнение с Эльдаром Муртазиным (32...
У рубриці DOU Проектор всі охочі можуть презентувати свій продукт (як стартап, так і ламповий pet-проект). Якщо вам є про...
Яндекс.Метрика