От легаси к 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.

Похожие статьи:
Организатор: SmartMe UniversityТренер: Швайка Алексей Интерфейс становится плоским, а это означает что нужно находить новый тип интерактивного...
Спілка українських підприємців (СУП) закликає владу відмовитися від запровадження обовʼязкової звітності щодо контрольованих...
Руслан Коптев познакомился с программированием в 14 лет, когда родители подарили ему на Новый год стартовый набор Arduino,...
Escape rooms are fast becoming one of the most entertaining ways to spend an evening, as people want to try new experiences and move away from more traditional ways of entertainment. We thought we’d put together a few...
Другий міський фестиваль винахідників Kyiv Mini Maker Faire відбудеться 14 листопада на ВНДХ. Він об’єднає більше 100 учасників,...
Яндекс.Метрика