Устаревшая миграция

4 вопроса, на которые следует обратить внимание при миграции программных сервисов

Спланируйте миграцию программных сервисов и сделайте это без простоев и инцидентов

Вступление

Термин Legacy Migration широко используется в мире техники для описания процесса миграции программного стека, инфраструктуры или архитектуры программного обеспечения из одного состояния в другое. Некоторые из распространенных вариантов использования, которые можно описать термином «Миграция из прежних версий», перечислены ниже:

  • Переход от монолитной к микросервисной архитектуре.
  • Перенос сервисов из локальной в облачную среду.
  • Миграция сервисов в контейнеры / докер / Kubernetes.

В этом посте я выделю пару моментов, которые необходимо учитывать при переносе программных сервисов из одной инфраструктуры в другую. Например, при переносе сервиса с Docker Swarm на Kubernetes. Некоторые моменты, которые я выделю, не относятся к этому типу миграции и могут быть применены к любой миграции службы.

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

Планирование миграции

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

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

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

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

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

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

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

Необходимые изменения исходного кода. Один из антишаблонов разработки программного обеспечения - это жесткое кодирование конфигураций или смешивание конфигурации или данных с исходным кодом приложения (бизнес-логика).

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

PoC: всегда необходимо подтверждение концепции процесса миграции, которое может дать больше информации о проблемах миграции и границах программного обеспечения, которые являются необходимыми шагами для завершения процесса миграции.

Например, в случае, если мы пытаемся перенести приложение Ruby on Rails для работы в кластерах Docker, Poc поможет выяснить, по крайней мере, следующие моменты:

→ Как создавать образы докеров и управлять ими.

→ Обеспечить стандарты для написания Dockerfile

→ Понять, что необходимо для определения конвейеров CI / CD.

→ Как управлять образами докеров и развертывать их в разных средах.

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

→ Поддержка нескольких сред для тестирования, тестирования и производства.

→ Рассмотрите окружающую среду, основанную на взаимодействии сервисов и зависимостях сервисов.

→ Подумайте об автоматизации развертываний и определении CI / CD для поддерживаемых сред.

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

→ Определите основные этапы процесса миграции.

→ Определите задачи и зависимости задач в каждой из вех.

→ Определите даты выполнения каждой из задач в дорожной карте.

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

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

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

Подписчики / Потребители

Роль этого типа службы заключается в обеспечении асинхронной связи между различными службами, составляющими стек приложения. Некоторые из хорошо известных инструментов, поддерживающих этот шаблон, - это RabbitMQ и Kafka.

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

Чтобы упростить миграцию услуг этого типа, необходимо внимательно учесть следующие моменты:

  • Подписчики / потребители не должны выполнять обработанные сообщения; вместо этого они должны хранить сообщения как фоновые задания. Это поможет нам сделать асинхронную связь более устойчивой в случае сбоев. Фоновые задания смогут повторить попытки выполнения сообщений.
  • Подписчики / потребители должны иметь минимальные зависимости. Я действительно полагаюсь только на брокера сообщений для чтения сообщений и использую другую зависимость от базы данных для хранения фоновых заданий. Это поможет в перемещении служб с одного узла на другой - или даже в другой кластер, если доступны и база данных, и брокер сообщений. Нам не нужно беспокоиться об исполнении сообщений, поскольку это будет выполняться фоновыми заданиями.
  • Об успехе миграции этого типа службы можно заключить, если новые службы смогут читать сообщения и сохранять их в качестве фоновых заданий.
  • Прекращение работы старых экземпляров подписчика может быть выполнено, как только новые службы станут активными и будут обрабатывать сообщения.

Дела по расписанию

Запланированные задания (также известные как кукурузные задания) - это задания, которые выполняются в заранее определенные моменты времени.

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

  • Задания, которые можно выполнять несколько раз - одновременно или в разное время. Одним из примеров является синхронизация информации между различными службами.
  • Задания, которые необходимо выполнить в определенное время и только один раз. Как импорт транзакций для платежного шлюза.

Миграция первого типа запланированных задач проще, чем другого типа, поскольку его можно выполнять в нескольких экземплярах; однако нам по-прежнему необходимо убедиться, что все зависимости для этих запланированных задач доступны в новой инфраструктуре.

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

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

Фоновые задания

Фоновые задания - это асинхронные службы, которые будут читать заданные задания из базы данных (или других источников) и пытаться выполнить каждое из заданных заданий. Обычно они также предоставляют механизм повтора в случае сбоя выполнения.

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

  • Все зависимости рабочих мест должны быть доступны для новых сервисов.
  • Никаких жестко запрограммированных конфигураций, путей и т. Д. В исходном коде.
  • Проверьте наличие конфликтов, которые могут возникнуть в результате создания новых служб. Например, если задания обрабатывают и генерируют какие-либо данные для конкретной среды, такие как абсолютные пути.
  • Различия между тестовой, промежуточной и производственной средами с обеих сторон.

Один из способов упростить перенос фоновых заданий - классифицировать фоновые задания и обрабатывать их отдельно. Процесс описан ниже:

  • Задания должны быть классифицированы, и каждый тип должен быть назначен в отдельную очередь.
  • Новые службы фоновых заданий создаются и настраиваются для обработки заданий только из определенной группы, например «migrate-jobs».
  • Измените очередь заданий одно за другим с очереди по умолчанию на очередь «migrate-jobs».
  • После успешного выполнения перемещенного задания переходите к следующему.
  • В случае сбоев из-за ошибок или исправления неправильной конфигурации повторно разверните фоновые задания.

Веб-серверы

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

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

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

  • Разверните сервисы в тестовых средах.
  • Выполните тестирование производительности и убедитесь, что новая установка может обрабатывать трафик приложения.
  • Разверните сервис в производственной среде в пассивном режиме (на данный момент трафик на эти экземпляры не перенаправляется).
  • Выполните дымовое тестирование новых экземпляров, чтобы убедиться, что они могут обрабатывать веб-запросы. Здесь вы создаете временные записи DNS для доступа к новым службам.
  • Исправьте все ошибки, обнаруженные в результате тестирования, и выполните повторное развертывание.
  • Унифицируйте настройку балансировки нагрузки для служб как в устаревшей, так и в новой среде. Это важный шаг, позволяющий перенести службы без простоев.
  • Добавьте один узел из новой среды в балансировщик нагрузки службы. Этот шаг активирует сервисы в новой инфраструктуре.
  • Следите за новыми экземплярами и их журналами на предмет исключений или ошибок. Если что-то найдено, удалите узел из балансировщика нагрузки, устраните проблему и повторите попытку.
  • Добавьте больше узлов в подсистему балансировки нагрузки, чтобы получить больше трафика к новому экземпляру и продолжить мониторинг служб.
  • Наконец, начните удалять старые экземпляры из балансировщика нагрузки, чтобы отключить их.

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

Заключение

Миграция сервисов из одного состояния в другое - сложная задача, и ее нужно выполнять осторожно, особенно в случаях, когда услуги общедоступны и потребляются конечными потребителями. Для разных типов сервисов используются разные методы миграции. Асинхронные службы легче перенести, особенно если у них ограниченные зависимости.

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