Про микросервисы сейчас говорят все. Почти каждая встреча, конференция и митап не обходятся без рассказа о том, что такое микросервисы и как они хороши, как уменьшают сложность проекта и тп.
Основной посыл всех этих докладов — микросервисы помогают уйти от излишней сложности и запутанности проекта. Но, как по мне, от сложности не избавиться совсем, нельзя переделать проект, чтобы сразу всё стало просто. Сложность из одной области перейдет в другую.
Например: был очень сложный запутанный монолит, мы его разбили на несколько сервисов, каждый из них выглядит прекрасно, любой сможет разобраться с кодом, но что происходит с окружением? Сложность растет: это и распределенные транзакции, которые нужно журналировать так, чтобы понять, что это одна транзакция; для каждого сервиса прибавляется CI/CD и поставка; схема взаимодействия становится нетривиальной.
Самые спорные тезисы или утверждения, которые я слышал на докладах и с которыми я готов спорить:
Вход в проект монолита дороже для новых членов команды. Почему-то принято оценивать стоимость вхождения в проект по тому, как быстро новый разработчик начнёт делать задачи. Да, в маленьком сервисе он разберется очень быстро и задачу выдаст очень быстро (тем более по спецификации, «что написали, то я и сделал»).
Но как насчет других членов команды?
Новый тестировщик будет разбираться с интеграционной моделью. Протестировать сервис — это хорошо, но кроме тестирования контракта сервиса нужно проверить бизнес-процесс, который затрагивает несколько сервисов.
Новый аналитик на первых порах может вообще голову сломать, пока разберется во всех хитросплетениях внутренних вызовов.
Микросервисы позволяют чаще релизить. Микросервисы дорабатывать быстрее, потому что они разнесены на несколько параллельных задач, которые разрабатываются и тестируются параллельно, и остается только проверить интеграцию (без учета времени на аналитику).
С монолитом тоже можно так делать, всё зависит от декомпозиции задачи. Чаще всего в самом начале будет одна задача — сделать общую функциональность (общую БД подправить, или интерфейс доработать), а дальше каждый будет пилить свои подзадачи и отдавать их в тестирование.
И время выпуска фичи, за которую платит бизнес, будет одинаковое. Фича будет закрыта только когда будут выпущены все компоненты. Микросервисы могут решить 99% задач, но пока не закроется последняя фича, их не выпустят в бой.
При использовании микросервисов усложняется инфраструктура. Это связано с тем, что нужно поддерживать работу не одного приложения, а множества сервисов. Нужно мониторить работоспособность всех сервисов, хорошо понимать зависимости сервисов по версиям, иметь CI/CD-планы для сборки сервисов и поставки, механизмы реагирования на выходы сервисов из строя, чтобы не легло всё остальное.
Вроде бы простые вещи, и в монолите мы должны делать всё то же самое. Только в монолите мы работаем над одним приложением, а с увеличением количества сервисов сложность растет, что требует от поддержки более высоких навыков.
Микросервисы добавляют сложность — новые библиотеки, новая функциональность для поддержки распределенных транзакций, для обработки ошибок других сервисов, отправки повторных запросов, отката транзакций. По большей части эти механизмы будут общими, и большинство разработчиков не полезут в «кишки», а будут только использовать их.
Но и в них могут быть ошибки, которые придётся чинить. Если с починкой мы справляемся без проблем, то чтобы раскатать изменения по 200—300 сервисам, понадобится время и развитые средства управления. А если понадобится пересобрать сервисы с обновленной библиотекой, а то и вызовы переделать (вот так починили, не предусмотрели), то всё это будет не весело.
Как обычно начинаются рассказы про прекрасный мир микросервисов? «Был у нас монолит, это был сплошной комок грязи, в котором всё запутанно и непонятно», плюс ещё картинку страшную покажут. И монолит уже стал чем-то пугающим, «будете плохо работать, ваш проект превратится в монолит». Но НЕТ.
Монолит может быть(и должен) понятным, структурированным, с ‘хорошим’ кодом, с документацией, как и микросервисный проект может превратиться в еще больший комок грязи, если не заниматься процессами разработки и не следить за качеством разработки.
Хороший вопрос, и ответ можете дать только вы. Потому что только вам известно, какие проблемы бизнеса вы решаете, каким будет проект. Нет серебряной пули, нет идеальной архитектуры, которую можно использовать и будет всегда “счастье”.
И в монолите, и в микросервисах следите за документацией и поддерживайте её в актуальном состоянии. С документацией лучше, чем без неё.
Выстраивайте такой процесс разработки, при котором качество кода будет только расти (ревью, модульные тесты). Но про качество можно целую книгу написать, это тема для отдельного большого разговора.
Простой и понятный код — это не про микросервисы, код априори таким должен быть.
Автоматизация тестирования — это тоже про качество кода.
Автоматизируйте всё, что можно автоматизировать — CI/CD. Наверное, есть такой стек технологий, который очень трудно затянуть в CI/CD, но 99% сборок/поставок можно автоматизировать.
Основной посыл всех этих докладов — микросервисы помогают уйти от излишней сложности и запутанности проекта. Но, как по мне, от сложности не избавиться совсем, нельзя переделать проект, чтобы сразу всё стало просто. Сложность из одной области перейдет в другую.
Например: был очень сложный запутанный монолит, мы его разбили на несколько сервисов, каждый из них выглядит прекрасно, любой сможет разобраться с кодом, но что происходит с окружением? Сложность растет: это и распределенные транзакции, которые нужно журналировать так, чтобы понять, что это одна транзакция; для каждого сервиса прибавляется CI/CD и поставка; схема взаимодействия становится нетривиальной.
Самые спорные тезисы или утверждения, которые я слышал на докладах и с которыми я готов спорить:
Вход в проект монолита дороже для новых членов команды. Почему-то принято оценивать стоимость вхождения в проект по тому, как быстро новый разработчик начнёт делать задачи. Да, в маленьком сервисе он разберется очень быстро и задачу выдаст очень быстро (тем более по спецификации, «что написали, то я и сделал»).
Но как насчет других членов команды?
Новый тестировщик будет разбираться с интеграционной моделью. Протестировать сервис — это хорошо, но кроме тестирования контракта сервиса нужно проверить бизнес-процесс, который затрагивает несколько сервисов.
Новый аналитик на первых порах может вообще голову сломать, пока разберется во всех хитросплетениях внутренних вызовов.
Микросервисы позволяют чаще релизить. Микросервисы дорабатывать быстрее, потому что они разнесены на несколько параллельных задач, которые разрабатываются и тестируются параллельно, и остается только проверить интеграцию (без учета времени на аналитику).
С монолитом тоже можно так делать, всё зависит от декомпозиции задачи. Чаще всего в самом начале будет одна задача — сделать общую функциональность (общую БД подправить, или интерфейс доработать), а дальше каждый будет пилить свои подзадачи и отдавать их в тестирование.
И время выпуска фичи, за которую платит бизнес, будет одинаковое. Фича будет закрыта только когда будут выпущены все компоненты. Микросервисы могут решить 99% задач, но пока не закроется последняя фича, их не выпустят в бой.
О чем еще не говорят
Сложность растет
При использовании микросервисов усложняется инфраструктура. Это связано с тем, что нужно поддерживать работу не одного приложения, а множества сервисов. Нужно мониторить работоспособность всех сервисов, хорошо понимать зависимости сервисов по версиям, иметь CI/CD-планы для сборки сервисов и поставки, механизмы реагирования на выходы сервисов из строя, чтобы не легло всё остальное.
Вроде бы простые вещи, и в монолите мы должны делать всё то же самое. Только в монолите мы работаем над одним приложением, а с увеличением количества сервисов сложность растет, что требует от поддержки более высоких навыков.
Микросервисы добавляют сложность — новые библиотеки, новая функциональность для поддержки распределенных транзакций, для обработки ошибок других сервисов, отправки повторных запросов, отката транзакций. По большей части эти механизмы будут общими, и большинство разработчиков не полезут в «кишки», а будут только использовать их.
Но и в них могут быть ошибки, которые придётся чинить. Если с починкой мы справляемся без проблем, то чтобы раскатать изменения по 200—300 сервисам, понадобится время и развитые средства управления. А если понадобится пересобрать сервисы с обновленной библиотекой, а то и вызовы переделать (вот так починили, не предусмотрели), то всё это будет не весело.
Монолит — не большой комок грязи(big ball of mud)
Как обычно начинаются рассказы про прекрасный мир микросервисов? «Был у нас монолит, это был сплошной комок грязи, в котором всё запутанно и непонятно», плюс ещё картинку страшную покажут. И монолит уже стал чем-то пугающим, «будете плохо работать, ваш проект превратится в монолит». Но НЕТ.
Монолит может быть(и должен) понятным, структурированным, с ‘хорошим’ кодом, с документацией, как и микросервисный проект может превратиться в еще больший комок грязи, если не заниматься процессами разработки и не следить за качеством разработки.
Так что же использовать?
Хороший вопрос, и ответ можете дать только вы. Потому что только вам известно, какие проблемы бизнеса вы решаете, каким будет проект. Нет серебряной пули, нет идеальной архитектуры, которую можно использовать и будет всегда “счастье”.
И в монолите, и в микросервисах следите за документацией и поддерживайте её в актуальном состоянии. С документацией лучше, чем без неё.
Выстраивайте такой процесс разработки, при котором качество кода будет только расти (ревью, модульные тесты). Но про качество можно целую книгу написать, это тема для отдельного большого разговора.
Простой и понятный код — это не про микросервисы, код априори таким должен быть.
Автоматизация тестирования — это тоже про качество кода.
Автоматизируйте всё, что можно автоматизировать — CI/CD. Наверное, есть такой стек технологий, который очень трудно затянуть в CI/CD, но 99% сборок/поставок можно автоматизировать.