Как мигрировать монолит в микросервисы?
Просыпается бабка со скамейки у подъезда 👵🏻
Этот вопрос вызывает у меня рвотный рефлекс печаль уже больше 10 лет.
Мейнстрим сперва уверовал в микросервисы (лучше их нет на свете), затем уверовал в модульный монолит (мы не хипстеры, мы знаем как надо по феншую).
При этом реальность на земле за 10 лет не изменилась ни на дюйм.
Да, железо и совт стали комодити. Появилась культура DevOps. Это дало людям свободу от SOA архитектур, сформированных вокруг проприетарного совта и дорогого железа. Мы получили возможность формировать модули вокруг бизнес логики.
Что люди сделали с этой свободой? Ушли от SOA – большие молодцы. Рубль – отличный мотиватор. Но ушли не в микросервисы а в зоопарк франкенштейнов, пусть и называют это микросервисами.
Архитектура современных систем распределенная. Да, все просто – она распределенная. Она состоит из кучи паттернов, совмещенных вместе. Там и микросервисы, и micro kernel, и event based, и гексагональная, и много еще какая. И это хорошо. Gang of Four учила нас 30 лет назад, что нужно быть прагматичными с паттернами.
Возвращаюсь от брюзжания к топику 😜 На самом деле вопрос стоит по другому – как мигрировать монолит в распределенную архитектуру? Глобально существует 2 подхода.
1️⃣Business first Часто мы решаемся уйти в распределенную архитектуру, чтобы получить более эффективное горизонтальное масштабирование. По другим причинам тоже, но я возьму эту для объяснения, с остальными тоже самое актуально. Это важно для наиболее критичного для бизнеса функционала. Логично мигрировать сперва самое важное для бизнеса, а потом менее важное (до миграции менее важного можно и не дойти и это тоже нормально).
Но тут возникает одна проблема – самое важное для бизнеса часто является самым популярным функционалом, от которого многое зависит. Уже визуализировали боль? При миграции компонента, от которого зависит много других компонентов, мы имеем много подвижных частей, каждая из которых может сломаться в процессе.
2️⃣Dependency first Мы формируем карту зависимостей у каждого компонента. Затем мигрируем компоненты с наименьшим количеством зависимых компонентов. Визуализировали? С каждой итерацией мы уменьшаем количество зависимых компонентов и на последней итерации компонент, от которого зависела куча компонентов, уже имеет минимум зависимых.
Выглядит как серебряная пуля. Почему же мы всегда не идем от зависимостей? Потому что сложно объяснить бизнесу, зачем мы занимаемся миграцией самого важного функционала для бизнеса в последнюю очередь 😁
Мы уже знаем, что в архитектуре не бывает эффективного решения на все случаи жизни. Поэтому для каждой миграции мы жонглируем обоими подходами а иногда/редко даже используем оба подхода одновременно. В каком-то смысле это вопрос управления рисками и сопутствующими затратами.