Микросервисы — комбинаторный взрыв версий

Привет, Хабр! Представляю вашему вниманию авторский перевод статьи Microservices – Combinatorial Explosion of Versions.

image

Во времена когда мир IT постепенно переходит на микросервисы и инструменты вроде Kubernetes, все более заметной становится лишь одна проблема. Эта проблема — комбинаторный взрыв версий микросервисов. Все же IT сообщество полагает, что сегодняшняя ситуация значительно лучше, чем «Dependency hell» предыдущего поколения технологий. Тем не менее, управление версиями микросервисов весьма сложная проблема. Одним из доказательств этому могут служить статьи вроде «Верните мне мой монолит».

Если вы читая этот текст пока не понимаете проблему, позвольте мне объяснить. Предположим, ваш продукт состоит из 10 микросервисов. Теперь предположим, что для каждого из этих микросервисов выходит 1 новая версия. Только 1 версия — надеюсь, мы все можем согласиться, что это весьма тривиальный и незначительный факт. Теперь однако посмотим еще раз на наш продукт. С одной лишь новой версией каждого компонента у нас теперь появилось 2^10 — или 1024 пермутаций того, как можно составить наш продукт.

Если еще осталось непонимание, позвольте мне разложить математику. Итак, мы имеем 10 микросервисов, каждый получает одно обновление. То есть, мы получаем 2 возможные версии на каждый микросервис (либо старую, либо новую). Теперь, для каждого из компонентов продукта мы можем использовать любую из этих двух версий. Математически, это то же самое как если бы у нас было двоичное число из 10 знаков. К примеру, скажем что 1 — это новая версия, а 0 — старая версия — тогда одна возможная пермутация может быть обозначена как 1001000000 — где 1й и 4й компоненты обновлены, а все остальные нет. Из математики мы знаем, что двоичное число из 10 знаков может иметь 2^10 или 1024 значений. То есть, мы подтвердили масштабы числа, с которым имеет дело.

Продолжим рассуждения далее — а что произойдет, если у нас будет 100 микросервисов и у каждого 10 возможных версий? Вся ситуация становится весьма неприятной — теперь у нас 10^100 пермутаций — а это огромное число. Тем не менее, я предпочитаю обозначить эту ситуацию именно так, потому что теперь мы не прячемся за словами вроде «kubernetes», а встречаем проблему как она есть.

Почему меня так восхищает эта проблема? Отчасти потому что работая ранее в мире NLP и AI мы много обсуждали проблему комбинаторного взрыва где-то 5-6 лет назад. Только вместо версий у нас были отдельные слова, а вместо продуктов у нас были предложения и параграфы. И хотя проблемы NLP и AI остаются в большой степени так и нерешенными, надо признать что за последние несколько лет был сделан существенный прогресс (на мой взгляд, прогресс мог бы быть большим, если бы люди в отрасли немного меньше внимания уделяли машинному обучению и немного больше другим техникам — но это уже офф-топик).

Возвращусь к миру DevOps и микросервисов. Перед нами стоит огромная проблема, маскирующаяся как слон в Кунсткамере — ведь что я часто слышу — «просто возьми kubernetes и helm, и все будет хорошо!» Но нет, все не будет хорошо, если все оставить как есть. Более того, аналитическое решение этой проблемы не представляется приемлемым в виду сложности. Как и в NLP, нам следует сначала подойти к этой проблеме путем сужения области поиска — в данном случае за счет исключения устаревших пермутаций.

Одна из вещей, которая может помочь — я писал в прошлом году о необходимости поддерживать минимальный разброс между версиями выложенными для клиентов. Также важно отметить, что хорошо проработанный процесс CI/CD очень помогает в сокращении вариаций. Однако, сегодняшнее положение дел с CI/CD не достаточно хорошо для решения проблемы пермутаций без дополнительного инструментария учета и отслеживания компонентов.

Что нам нужно — это система экспериментов на стадии интеграции, где мы могли бы определить фактор риск по каждому компоненту, а также иметь автоматизированный процесс обновления различных компонентов и тестирования без вмешательства оператора — чтобы видеть что работает, а что нет.

Такая система экспериментов могла бы выглядеть следующим образом:

  1. Девелоперы пишут тесты (это критический этап — потому что иначе у нас нет критерия оценки — это как разметка данных в машинном обучении).
  2. Каждый компонент (проект) получает свою собственную CI систему — этот процесс на сегодняшний день хорошо проработан, и вопрос создания CI системы для единичного компонента во многом решен
  3. «Умная система интеграции» собирает результаты различных CI систем и собирает проекты-компоненты в финальный продукт, запускает тестирование и наконец вычисляет наиболее короткий путь к получению нужной функциональности продукта исходя из существующих компонентов и факторов риск. Если совершить обновление невозможно, эта система оповещает разработчиков о имеющихся компонентах и на каком из них происходит ошибка. Еще раз повторю, что система тестов здесь обладает критической важностью — так как система интеграции использует тесты как критерий оценки.
  4. CD система, которая затем получает данные из «Умной системы интеграции» и производит непосредственно обновление. Эта стадия заканчивает цикл.

Подытоживая, для меня одна из самых больших проблем сейчас — это отсутствие такой «Умной системы интеграции», которая бы связывала различные компоненты в продукт и таким образом позволяла отслеживать, каким образом продукт в целом составлен. Мне будут интересны мысли сообщества по этому поводу (спойлер — я сейчас работаю над проектом Reliza, которая может стать такой умной системой интеграции).

Одна последняя вещь, которую я хочу упомянуть, — для меня монолит не является приемлемым для любого проекта хотя бы среднего размера. Для меня вызывают большой скептицизм попытки ускорить время реализации и качество разработки за счет возвращения к монолиту. Во-первых, монолит имеет похожую проблему управления компонентами — среди различных библиотек, из которых он состоит, однако все это не так заметно и проявляется в первую очередь во времени, которое тратят разработчики. Следствием проблемы монолита является фактическая невозможность вносить изменения в код — и крайне медленная скорость разработки.

Микросервисы улучшают ситуацию, однако затем микросервисная архитектура сталкивается с проблемой комбинаторного взрыва на стадии интеграции. Да, в целом, мы передвинули ту же самую проблему — со стадии разработки на стадию интеграции. Однако, на мой взгляд, подход микросервисов все же приводит к лучшим результатам, и команды достигают результатов быстрее (вероятно, в основном, из-за уменьшения размеров единицы разработки — или batch size). Однако, переход от монолита к микросервисам пока не дал достаточного улучшения процесса — комбинаторный взрыв версий микросервисов — это огромная проблема, и у нас есть большой потенциал улучшения ситуации по мере ее решения.

Специально для сайта ITWORLD.UZ. Новость взята с сайта Хабр