Неделя 01 Прод
Три новых модуля сломались на одних данных
Отображение показывает пустой блок. Проверка ответа возвращает 500. Ночная выгрузка падает.
Протокол 002
Старую систему заменяют по частям, не останавливая прод.
Неделя 01 Прод
Отображение показывает пустой блок. Проверка ответа возвращает 500. Ночная выгрузка падает.
Это платформа онлайн-обучения, которая 10 лет росла как Rails-монолит. Новые запросы бизнеса всё чаще упирались в старую модель и растягивались на месяцы, но остановить сервис и переписать всё сразу было нельзя. Поэтому команда переносила прикладной слой в .NET по одному маршруту: переключённые запросы уходили в новую систему, остальные продолжал обслуживать Rails. База пока оставалась общей, поэтому новый код встречал те же поля, разные типы значений и исключения, которые за 10 лет накопились в старой системе.
Проблема проявилась в первую же неделю: пришли 3 отчёта об ошибках – пустой экран, HTTP 500 при проверке ответа и упавшая ночная выгрузка. Ошибки возникли в разных модулях и сначала выглядели не связанными друг с другом. Найдите их общий источник, затем выберите 2 первых рубежа миграции. Третий станет следующим дорогим изменением: каждый порядок переносит риск в другое место.
Основано на реальной миграции. Названия проекта и данные обезличены.
Форма данных из старой системы пересекла границу 3 раза. Новый код повторил её неопределённость.
Реальная хронология заканчивается доказанной причиной. Порядок решений ниже – архитектурный сценарий.
Переключение
Все 3 действия обязательны. Первое изменит цену 2 следующих.
Объём
Оставить в миграции только маршруты, которые блокируют развитие.
Маршрутизатор
Переключать каждый маршрут отдельно и возвращать его в Rails одним изменением настройки.
Сверки
Сравнивать Rails и .NET на реальных входных данных и побочных эффектах.
Цена следующих действий появится после первого выбора.
Ниже показаны все 6 порядков. При включённом JavaScript останется только выбранный результат.
Порядок изменений
Первые маршруты переключаются до появления полного эталона поведения.
Зафиксировать поведение
Сравнивать Rails и .NET на реальных входных данных и побочных эффектах.
Порядок изменений
Данные с прода приходят позже, зато каждое расхождение уже объяснимо.
Сделать переключение обратимым
Переключать каждый маршрут отдельно и возвращать его в Rails одним изменением настройки.
Порядок изменений
До ограничения объёма обе системы успевают поработать параллельно.
Зафиксировать поведение
Сравнивать Rails и .NET на реальных входных данных и побочных эффектах.
Порядок изменений
Эталон поведения строится для области, которую ещё не решили переносить.
Ограничить объём
Оставить в миграции только маршруты, которые блокируют развитие.
Порядок изменений
Часть дорогих сверок отбрасывается вместе с маршрутами, которые решили не переносить.
Сделать переключение обратимым
Переключать каждый маршрут отдельно и возвращать его в Rails одним изменением настройки.
Порядок изменений
Причины расхождений понятны, но объём ограничивается последним и поэтому дорого.
Ограничить объём
Оставить в миграции только маршруты, которые блокируют развитие.