Моноліт → мікросервіси
Міграція з моноліту на мікросервіси — це перехід наявної системи на сервіси без зупинки поставки. Міграція, яка працює, — це не проєкт із цільовою архітектурою й датою завершення, а послідовність окремо обґрунтованих виділень за фасадом, кожне з яких достатньо мале, щоб його скасувати. Складне тут ніколи не код, а поділ даних.
- Патерн
- Strangler fig
- Одиниця роботи
- Одне виділення
- Найскладніше
- Поділ даних
Почніть з обмеження, а не з цілі
Більшість міграцій починається з картинки кінцевої точки — схеми з дванадцяти сервісів — і рухається назворот. Саме через цей порядок так багато з них тягнуться два роки й завершуються вісьмома сервісами, одним монолітом, у якому досі лежить головна логіка, і командою, повільнішою, ніж на старті.
Порядок, що працює, починається з названого обмеження, яке можна виміряти сьогодні. «Платежі й каталог на спільному релізі, і платежі чекають три тижні на непов’язану регресію». «Обробці зображень потрібно ввосьмеро більше пам’яті, ніж усьому іншому, і ми платимо за це на сорока інстансах». «Рушій рекомендацій має бути на Python, а решта — ні». Кожне з цих формулювань називає конкретну річ для виділення й дає спосіб потім зрозуміти, чи спрацювало.
Патерн strangler fig
Патерн названо на честь рослини, що обростає дерево, поступово перебирає його опорну роль і лишає оригінал порожнім. У програмному вигляді: поставте фасад перед наявною системою, спрямуйте через нього все, а потім переносьте функціональність за цим фасадом по одному маршруту.
Фасад ставлять першим — до того, як щось виділено. Цей порядок важливий: із фасадом на місці перше виділення є зміною маршрутизації, і відкат — теж. Без нього перше виділення є зміною в кожному викликачі, і відкат — ще однією зміною в кожному викликачі.
Цінність патерну не у формі, а у властивості, яку він гарантує: у кожен момент існує рівно одна робоча система, і кожен крок скасовується за час перемикання маршруту. Порівняйте з альтернативою, до якої тягнуться, — будувати заміну поруч і перемкнутися, коли буде готово, — де ви утримуєте дві системи, стара змінюється під новою, а весь ризик приходить в один день.
Що виділяти першим
Не найскладніше і не найважливіше. Перше виділення — це репетиція: його завдання навчити команду пайплайну, деплою, трасуванню, чергуванню й поділу даних, і зробити це тоді, коли ціна помилки низька. Беріть щось із малою кількістю залежностей, чіткою межею й малим радіусом ураження: сповіщення, генерацію PDF, обробку зображень, публічний API лише для читання.
Від другого виділення впорядковуйте за названим обмеженням. І тримайте кожне достатньо малим, щоб воно завершувалося за кілька тижнів: виділення, що триває пів року, перестало бути зворотним у будь-якому практичному сенсі, бо моноліт, з якого воно вийшло, за цей час поїхав уперед.
Поділ даних
Виділити код — це тиждень роботи. Виділити дані — це і є міграція, і саме тут команди, що пропустили цей розділ, опиняються з двома сервісами на одній базі, а це якраз той результат, якого вся вправа мала уникнути.
Послідовність, що працює, іде у зворотному до інтуїтивного порядку. Спершу розділіть таблиці всередині наявної бази: той самий інстанс, інша схема, жодних зовнішніх ключів через межу. Уже це виявляє кожну приховану залежність, бо кожен джойн через межу тепер не компілюється або валить тест, і ви виправляєте їх по одному, поки стара система працює. І лише коли межу ніщо не перетинає, схема переїжджає на власний інстанс — і лише тоді переїжджає код.
| Крок | Що дає | Що виявляє |
|---|---|---|
| Розділити схеми | Один інстанс, дві схеми, без ключів і джойнів через межу. | Кожну приховану зв’язність, дешево |
| Перевести читання на інтерфейс | Викликачі перестають торкатися таблиць і починають викликати метод. | Запити, про існування яких ніхто не знав |
| Писати в обидві, читати зі старої | Нове сховище наповнюється, і його можна звіряти зі старим. | Де вони розходяться — до того, як це важить |
| Перемкнути читання, писати в обидві | Бойовий трафік на новому сховищі зі шляхом назад того ж дня. | Продуктивність, якої не показували тестові дані |
| Припинити старий запис | Поділ став справжнім, старі таблиці можна прибрати. | Той один звіт, що досі з них читає |
Дві техніки, що роблять більшість роботи
Прошарок проти псування
Новому сервісу знадобляться дані зі старої системи, а модель старої системи зазвичай сформована п’ятнадцятьма роками випадковостей: колонка status з одинадцятьма значеннями, запис клієнта, який водночас є адресою доставки. Якщо новий сервіс говорить цією моделлю, він успадковує її назавжди — і виділяти його не було сенсу.
Прошарок проти псування — це межа перекладу: тонкий шматок коду, який з одного боку говорить старою моделлю, а з іншого — моделлю нового сервісу, і належить новому сервісу. Він навмисно потворний, навмисно ізольований і навмисно тимчасовий: коли старе джерело нарешті зникне, ви видалите один компонент, а не виколупуватимете модель із кожного файлу.
Закон Конвея, застосований свідомо
Конвей помітив, що структура системи зрештою віддзеркалює структуру комунікації організації, яка її будувала. У міграції це не курйоз, а найсильніша сила в кімнаті. Якщо виділеним сервісом спільно володіють чотири команди, у ньому виростуть чотири внутрішні фракції й координаційна зустріч, і він не буде незалежно деплойним, хоч би що казала схема.
Застосований свідомо — це іноді називають зворотним маневром Конвея — він стає інструментом: змініть межі команд на ті, які ви хочете бачити в сервісах, і архітектура піде слідом. Це також задає чесну верхню межу міграції. Ви не можете отримати більше сервісів, ніж маєте команд, щоб ними володіти, а сервіс, яким не володіє ніхто, гниє в розподіленій системі швидше, ніж гнив би в моноліті.
Коли зупинитися
Ніщо в цьому патерні не вимагає, щоб моноліт зник, а перетворення його зникнення на мету — це те, як міграція переживає власне обґрунтування. Кожне виділення обґрунтовувалося обмеженням; коли решта частин нічого не блокує, за рештою виділень немає жодного аргументу, крім симетрії.
Постійний гібрид — три-чотири сервіси навколо добре модуляризованого ядра, у якому досі лежить більша частина предметної області, — це поширений і цілком поважний кінцевий стан. У більшості організацій це ще й точка найкращої віддачі: частини зі справжньою потребою в незалежності її мають, а частини без такої потреби не платять за мережу, яка їм не була потрібна.
Міряйте міграцію за названим обмеженням, а не за кількістю сервісів. Якщо платежі тепер релізяться двічі на тиждень замість разу на місяць, це виділення себе окупило, і ви можете сказати це числом. Якщо кількість сервісів зросла з одного до дев’яти, а час від коміту до продакшену не зрушив, дев’ять сервісів — це не поступ, а дев’ять пайплайнів деплою.
Як це виявляється в реальній поставці
Міграція конкурує з поставкою фіч за тих самих людей, і цю конкуренцію вирішує той, хто присутній у кімнаті, коли планують квартал. Міграція як фонова діяльність тих, у кого є вільний час, триває три роки й не завершується ніколи; міграція як повне заморожування фіч програє суперечку на першому ж комерційному дедлайні. Виживає заявлена частка потужності — команда або фіксована частка кварталу кожної команди — де кожне виділення приземляється як видимий результат, а не як прогрес за планом.
Де вона вироджується
- Повне переписування поруч із живою системою: увесь ризик приходить в один день, а стара система тим часом рухається далі.
- Виділити код і лишити спільну базу — це розподілений моноліт із додатковими кроками.
- Почати з найскладнішого центрального компонента — команда вчиться механіці там, де помилки коштують найдорожче.
- Виділення, що тягнуться місяцями, перестають бути зворотними, бо моноліт під ними поїхав уперед.
- Подвійний запис без звірки — сховища тихо розходяться.
- Новий сервіс говорить старою моделлю даних — і завозить у себе той безлад, від якого тікав.
- Рахувати сервіси як міру поступу замість обмеження, що виправдало роботу.
Коли це застосовувати
Застосовуйте, коли
- Ви можете назвати конкретне обмеження, яке накладає нинішня форма, і виміряти його.
- Безперервний деплой і трасування вже працюють, тож виділений сервіс експлуатується з першого дня.
- Є команда, готова володіти виділеним сервісом у продакшені.
- Поставка може тривати під час міграції — фасад робить кожен крок зворотним.
- Постійний гібрид є прийнятним кінцевим станом, а не провалом.
Уникайте, коли
- Причина в тому, що код заплутаний, — спершу модуляризуйте всередині моноліту: це дешевше й однаково є передумовою.
- Немає кого виділити на володіння новими сервісами — вони будуть спільними, а отже зв’язаними.
- План — це переписування з датою переходу, а не послідовність зворотних кроків.
- Дані неможливо поділити, бо предметна область справді потребує транзакційної консистентності через межу.
- Міграцію міряли б створеними сервісами, а не знятим обмеженням.
Було корисно?
Поділіться з тим, хто працює над тією ж задачею.