Главная Блог Модернизация legacy-систем: стратегия, которая не парализует бизнес

Модернизация legacy-систем: стратегия, которая не парализует бизнес

Модернизация legacy — это не переписывание с нуля. Это стратегия которая позволяет параллельно разрабатывать новую систему и поддерживать старую. Разберём как это делать правильно.

15 минут
Сергей Морозов
Architecture
# Модернизация legacy-систем: стратегия, которая не парализует бизнес Legacy-система это когда у вас code из 2010-х, базу никто не трогает, есть one guy, который помнит, как это работает. Попроси добавить функцию — вероятность сломать что-то равна 50/50. За последний год я видел пять компаний, которые попробовали модернизировать legacy с нуля. Все пять раз это закончилось плохо: потратили 500k–1M, полгода времени, и в конце оказалось, что новая система не работает так как старая. Правильная стратегия: strangler pattern. Это когда вы параллельно разрабатываете новую систему и постепенно переводите трафик со старой. Старая система живёт ещё 1–2 года, но её функций всё меньше. ## Почему переписывание с нуля не работает ### Проблема 1: Неполное понимание требований Вы думаете что знаете как работает система. На самом деле есть 500 граничных случаев которые обрабатывает старая система. Когда вы переписываете — забываете про 20 из них. **Пример:** - Старая система: когда клиент вернул товар, она вычитает из дохода, но ТОЛЬКО если возврат в течение 30 дней. А если прошло 35 дней, вычитает из другой категории бухучёта. - Новая система v1: просто вычитает из дохода - Результат: в конце месяца бухгалтерия ломается потому что финансовые отчёты не совпадают ### Проблема 2: Данные несовместимы Старая система копила данные 15 лет. Когда мигрируете в новую — они не совпадают. **Пример:** - Старая BDD: есть 50k клиентов, но 30% имеют невалидный email (пробел в конце, заглавные буквы без нормализации) - Новая система: требует валидный email - Результат: не можете загрузить 30% клиентов. Приходится писать миграцию и чистить данные. ### Проблема 3: Бизнес продолжает меняться Пока вы переписываете, бизнес добавляет новые требования к старой системе. Потом вам нужно добавить их в новую. **Результат:** Новая система всегда отстаёт от старой. ## Стратегия strangler pattern Вместо переписывания с нуля делайте так: ``` Месяц 1: Выбираете один маленький модуль (например, управление ценами) Месяц 2–3: Разрабатываете новую систему управления ценами Месяц 3: Тестируете в parallel (новая и старая одновременно) Месяц 4: Переводите трафик на новую (старая живёт как backup) Месяц 5: Удаляете старый модуль (данные перенесли) ``` **Преимущества:** - Низкий риск: если что-то сломается, откатываетесь на старую - Понимание требований: вы разбираетесь в модуле пока разрабатываете новый - Бизнес продолжает работать: никаких простоев **Недостатки:** - Дольше: вместо 6 месяцев на переписывание, это займёт 2 года постепенной миграции - Сложнее: нужно поддерживать обе системы в parallel ## Как выбрать первый модуль для миграции ### Критерии выбора 1. **Независимость:** Модуль мало зависит от других частей системы - Хорошо: управление ценами, управление складом - Плохо: система биллинга (зависит от всего) 2. **Простота:** Модуль не очень сложный - Хорошо: 10–20k строк кода - Плохо: 500k строк кода с многолетней историей 3. **Частая смена требований:** Бизнес часто просит новые функции в этом модуле - Хорошо: управление каталогом товаров (часто меняется) - Плохо: система логирования (стабильна) 4. **Чёткие границы:** Модуль четко определён - Хорошо: управление документами (вход: документ, выход: обработанный документ) - Плохо: что-то, что пронизывает всю систему ## Как делать миграцию данных ### Шаг 1: Audit старых данных Перед миграцией проверьте: - Сколько данных (100k, 1M, 100M записей)? - Какие данные невалидны? - Какие данные потеряны/дублируются? ```sql -- Пример: проверка невалидных email SELECT COUNT(*) FROM users WHERE email IS NULL OR email = ''; SELECT COUNT(*) FROM users WHERE email NOT LIKE '%@%'; ``` ### Шаг 2: Напишите трансформацию данных Данные из старой системы редко совпадают со схемой новой. Нужна трансформация. **Пример:** ``` Старая: users.full_name = "Иванов Иван" Новая: users.first_name = "Иван", users.last_name = "Иванов" ``` Напишите скрипт миграции который: 1. Читает из старой BDD 2. Трансформирует 3. Пишет в новую BDD 4. Логирует ошибки (какие данные не мигрировались и почему) ### Шаг 3: Тестируйте миграцию на копии НЕ делайте миграцию на боевой системе. Сначала: 1. Сделайте бэкап боевой БД 2. Восстановите на тестовом сервере 3. Запустите миграцию 4. Проверьте что все данные совпадают (count, checksum) 5. Запустите тесты новой системы ### Шаг 4: Миграция и коммуникация День миграции: 1. Уведомьте клиентов за день: система будет недоступна 2 часа (к примеру) 2. Остановите старую систему (чтобы не было новых изменений) 3. Выполните миграцию данных (обычно 30–120 минут) 4. Запустите новую систему 5. Проверьте что данные в порядке (быстрые запросы) 6. Откройте доступ пользователям ## Как работать с двумя системами в parallel ### Проблема: Синхронизация Если старая и новая система работают одновременно, данные могут расходиться. **Решение 1: Event sourcing** - Старая система отправляет событие при изменении (например, "заказ создан") - Новая система слушает события и обновляет свои данные - Никогда старая и новая не конкурируют за запись **Решение 2: Dual-write** - При изменении вы пишете и в старую и в новую систему - Ночью синхронизируетесь (если данные разошлись) - Это дольше и сложнее, но проще чем event sourcing ### Проблема: Читаете из какой системы? Если клиент меняет данные в новой системе, они должны сразу видеть изменение. **Решение:** Читайте из новой системы. Если данных нет (ещё не мигрировали), читайте из старой. ``` GET /api/orders/123 → запрос в новую систему → если не найдено, запрос в старую систему → возвращаем результат (новая или старая) ``` ## Реальный кейс: Модернизация core-banking системы **Компания:** Крупный банк, legacy BDD система из 1990-х **Старая система:** - 500k строк COBOL кода - Биллион транзакций в день - Никто полностью не помнит как это работает **Стратегия:** - Выбрали модуль "управление счётами" (одна из самых независимых частей) - Разработали новую систему на Node.js + PostgreSQL за 4 месяца - Тестировали в parallel 2 месяца - Мигрировали 5M счётов за 3 часа ночью - В течение года постепенно перевели остальные модули **Результаты:** - Новая система обрабатывает платежи в 10x быстрее - Затраты на поддержку снизились на 40% - Разработчики теперь могут добавлять функции (раньше они были скованы COBOL) **Время:** 2 года полной миграции вместо 1 года на переписывание с нуля, которое бы сломалось ## Как не потратить время впустую ### 1. Не переписывайте всё сразу Strangler pattern: кусками, по одному модулю. ### 2. Не пытайтесь миграцию на лету Всегда делайте backup и тестируйте на копии. ### 3. Не забудьте про интеграции Новая система должна интегрироваться со всеми существующими системами старой. Это часто забывают и потом 2 месяца доделывают интеграции. ### 4. Мониторируйте разницу между старой и новой Случится что данные разойдутся. Нужны скрипты которые каждую ночь проверяют что в обеих системах одинаково. ### 5. Ведите документацию Для каждого модуля документируйте: - Какой трафик он обрабатывает - Какие интеграции есть - Какие граничные случаи есть - Как делалась миграция Это помогает не потерять информацию. ## Заключение Модернизация legacy — это не быстрый проект. Это долгий путь (1–3 года). Но если вы используете strangler pattern: - Риск низкий - Бизнес не парализован - Вы учитесь на каждом модуле - В конце у вас есть современная система Не переписывайте с нуля. Мигрируйте кусками. Жертвуйте скоростью разработки ради надёжности.

Хотите узнать больше?

Расскажите о вашей задаче — поможем найти решение

Обсудить проект