Прямой ответ
Strangler Fig — паттерн постепенной миграции legacy-систем (strangler fig — «дерево-душитель» — strangler fig — «новое растение обвивает старое, заменяет его» — strangler fig — техдолг — «legacy постепенно заменяется» — strangler fig); аналогия: дерево-душитель (strangler fig — «дерево обвивает старое, заменяет» — strangler fig — техдолг — «legacy постепенно заменяется» — strangler fig); проблема, которую решает: big-bang миграция (strangler fig — «всё сразу» — strangler fig — incident — «мигрировали всё — всё упало» — incident — strangler fig — риск слишком высок (strangler fig — «big-bang — риск» — strangler fig — техдолг); механика: постепенная замена (strangler fig — «по одной фиче» — strangler fig — техдолг — «фича 1 → новый сервис, фича 2 → новый сервис» — strangler fig — микросервисы — «legacy постепенно заменяется» — strangler fig); этапы: (1) Роутинг (strangler fig — прокси перед legacy (strangler fig — «прокси → legacy или новый сервис» — strangler fig — nginx/Kong (nginx — «прокси маршрутизирует» — nginx — strangler fig); (2) Миграция фичи (strangler fig — «фича 1 → новый сервис» — strangler fig — микросервисы — «новый сервис для фичи 1» — strangler fig); (3) Переключение (strangler fig — прокси переключает на новый сервис (strangler fig — «фича 1 → новый сервис» — strangler fig — deploy — canary (deploy — «5% трафика на новый сервис» — deploy — strangler fig); (4) Повтор (strangler fig — «фича 2 → новый сервис» — strangler fig — техдолг — «пока legacy не заменён» — strangler fig); (5) Удаление legacy (strangler fig — все фичи мигрированы (strangler fig — legacy удалён (strangler fig — техдолг — «legacy удалён» — strangler fig); когда Strangler Fig: legacy-системы (strangler fig — «legacy — Strangler Fig» — strangler fig — техдолг, монолит → микросервисы (микросервисы — «монолит → микросервисы» — микросервисы — strangler fig, риск высок (strangler fig — «big-bang — риск» — strangler fig — incident); когда НЕ Strangler Fig: новая система (strangler fig — «новая система — Strangler Fig не нужен» — strangler fig — техдолг, простая миграция (strangler fig — «простая миграция — big-bang» — strangler fig — техдолг); антипаттерны: Strangler Fig без прокси (strangler fig — «без прокси» — strangler fig — «не переключить» — strangler fig — прокси обязателен — nginx), Strangler Fig без canary (strangler fig — «без canary» — strangler fig — deploy — «сразу 100%» — deploy — canary обязателен — deploy), Strangler Fig без мониторинга (метрики — «миграция идёт» — метрики — алерты — алерты — «ошибки на новом сервисе» — incident).
Практика: Strangler Fig для монолита
Прокси (strangler fig — nginx (nginx — upstream legacy { server legacy:8080; } upstream new_service { server new:8081; } server { location /api/v1/users { proxy_pass } location / { proxy_pass } } (nginx — «/api/v1/users → новый сервис, остальное → legacy» — nginx — strangler fig); Миграция фичи (strangler fig — «фича 1 → новый сервис» — strangler fig — микросервисы — «новый сервис для фичи 1» — strangler fig — техдолг); Canary (deploy — «5% трафика на новый сервис» — deploy — strangler fig — nginx (nginx — split_clients "${remote_addr}" $backend { 5% new_service; * legacy; } (nginx — «5% на новый сервис» — nginx — deploy); Мониторинг (метрики: «errors on new service», «latency new vs legacy» — метрики — алерты — алерты — «ошибки на новом сервисе» — incident); Переключение (strangler fig — новый сервис ок (strangler fig — 100% трафика на новый (strangler fig — deploy — «100% на новый сервис» — deploy — strangler fig).
Практический сценарий: монолит → микросервисы через Strangler Fig
Контекст: монолит (микросервисы), боль: техдолг — «монолит — техдолг» — техдолг — big-bang миграция (strangler fig — «всё сразу» — strangler fig — риск (strangler fig — «big-bang — риск» — strangler fig — incident); решение — Strangler Fig: (1) прокси (nginx — nginx перед монолитом (nginx — «прокси → монолит» — nginx — strangler fig); (2) миграция фичи 1 (strangler fig — «фича 1 (users) → новый сервис» — strangler fig — микросервисы — «новый сервис для users» — strangler fig); (3) canary (deploy — «5% трафика на новый сервис» — deploy — strangler fig — nginx (nginx — «5% на новый сервис» — nginx — deploy); (4) мониторинг (метрики — «errors on new service» — метрики — алерты — алерты — «ошибки на новом сервисе» — incident); (5) переключение (strangler fig — новый сервис ок (strangler fig — 100% на новый (strangler fig — deploy — «100% на новый сервис» — deploy); (6) повтор (strangler fig — «фича 2 (orders) → новый сервис» — strangler fig — техдолг — «пока монолит не заменён» — strangler fig); (7) удаление legacy (strangler fig — все фичи мигрированы (strangler fig — монолит удалён (strangler fig — техдолг — «монолит удалён» — strangler fig); результат: монолит → микросервисы (микросервисы — «монолит заменён» — микросервисы — strangler fig — canary (deploy — «5% → 100%» — deploy — strangler fig — техдолг — «legacy удалён» — strangler fig); вывод: Strangler Fig решили задачу (монолит → микросервисы — микросервисы — ADR — «Strangler Fig без canary» — антипаттерн — техдолг).
FAQ
Strangler Fig против big-bang миграции — в чём разница и когда что? Strangler Fig (strangler fig — постепенная замена (strangler fig — «по одной фиче» — strangler fig — техдолг — «legacy постепенно заменяется» — strangler fig); Big-bang (strangler fig — «всё сразу» — strangler fig — incident — «мигрировали всё — всё упало» — incident — риск (strangler fig — «big-bang — риск» — strangler fig); когда Strangler Fig: legacy (strangler fig — «legacy — Strangler Fig» — strangler fig — техдолг, риск высок (strangler fig — «big-bang — риск» — strangler fig — incident), когда big-bang: новая система (strangler fig — «новая система — big-bang» — strangler fig — техдолг, простая миграция (strangler fig — «простая миграция — big-bang» — strangler fig); «big-bang для legacy» — антипаттерн (риск — incident — Strangler Fig безопаснее — strangler fig — ADR — техдолг).
Какие этапы Strangler Fig и как их выполнять?
- Роутинг (strangler fig — прокси перед legacy (strangler fig — «прокси → legacy или новый сервис» — strangler fig — nginx (nginx — «прокси маршрутизирует» — nginx); 2. Миграция фичи (strangler fig — «фича 1 → новый сервис» — strangler fig — микросервисы — «новый сервис для фичи 1» — strangler fig); 3. Переключение (strangler fig — canary (deploy — «5% трафика на новый сервис» — deploy — strangler fig); 4. Повтор (strangler fig — «фича 2 → новый сервис» — strangler fig — техдолг — «пока legacy не заменён» — strangler fig); 5. Удаление legacy (strangler fig — все фичи мигрированы (strangler fig — legacy удалён (strangler fig — техдолг — «legacy удалён» — strangler fig); «Strangler Fig без прокси» — антипаттерн (не переключить — strangler fig — прокси обязателен — nginx — ADR — техдолг).
Как мониторить миграцию через Strangler Fig? Мониторинг (метрики: «errors on new service» (метрики — «ошибки на новом сервисе» — метрики — алерты — алерты — incident), «latency new vs legacy» (метрики — «новый сервис медленнее legacy» — метрики — алерты — алерты), «traffic split» (метрики — «5% на новый сервис» — метрики — deploy — strangler fig); Алерты (алерты: «ошибки на новом сервисе» (алерты — алерт — incident — «новый сервис медленнее» (алерты — алерт — incident); «Strangler Fig без мониторинга» — антипаттерн (ошибки на новом сервисе — не заметили — incident — мониторинг обязателен — метрики — ADR — техдолг).
Когда Strangler Fig действительно нужен, а когда — оверхед? Нужен: legacy (strangler fig — «legacy — Strangler Fig» — strangler fig — техдолг, монолит → микросервисы (микросервисы — «монолит → микросервисы» — микросервисы — strangler fig, риск высок (strangler fig — «big-bang — риск» — strangler fig — incident); Оверхед: новая система (strangler fig — «новая система — Strangler Fig не нужен» — strangler fig — техдолг, простая миграция (strangler fig — «простая миграция — big-bang» — strangler fig — техдолг); «Strangler Fig для новой системы» — антипаттерн (оверхед — техдолг — «big-bang проще» — strangler fig — ADR — техдолг).
Источники: Martin Fowler (Strangler Fig), Microsoft Azure patterns, Sam Newman — ссылки в шапке.