Чтобы понять сложные вещи, нам на помощь очень часто приходят простые примеры из жизни. Сейчас предлагаем просто посмотреть на свой шкаф: возможно там царит полный порядок, а возможно, анархия. Для нашего примера понадобятся оба! Для начала представим и заглянем в шкаф, где полный беспорядок: все намешано, найти что-то сложно (не говоря о том, чтобы это что-то еще и было не мятое). Переместимся в шкаф, где царит порядок, и там есть отдельные ящики для каждой категории одежды. Всё разложено по полочкам, и без труда можно найти всё, что нужно. Так вот, микросервисная архитектура по своей сути похожа на этот шкаф с идеальным порядком, только вместо шмоток — программные компоненты. Микросервисы — это не просто модный тренд в IT, а реальная необходимость для многих компаний. Почему? Потому что современные приложения становятся всё более сложными и большими, а пользователи всё более требовательными. Никто не хочет ждать, пока приложение загрузится, или терпеть сбои из-за одной маленькой ошибки. И тут то мир подарил нам микросервисную архитектуру, дабы все упорядочить.
Микросервисная архитектура — это подход к разработке программного обеспечения, при котором приложение делится на множество независимых компонентов (или сервисов). Каждый из них отвечает за свою конкретную задачу и может работать автономно. Как в нашем идеальном шкафу: отдельная полка для футболок, штанов, носков и так далее. Что еще более важно, если какой-то компонент вышел из строя: то все остальные продолжают свою работу как ни в чём не бывало. Погрузимся же глубже.
Почему именно микросервисная архитектура?
Чтобы понять, почему микросервисы стали такими популярными, стоит понять, чем они отличаются от монолитного подхода. Рассмотрим монолитное приложение как один огромный швейцарский нож. Да, он умеет всё: и резать колбаску, и открывать пиво, и чинить батарею. Но вот проблема: если один из инструментов сломается (например, лезвие затупится), то пользоваться ножом становится неудобно или даже невозможно. Но рассмотрим аналог швейцарскому ножу, т.е. простой набор инструментов: нож, открывашка, отвёртка — каждый из них работает независимо от другого. Если нож затупился, то всё ещё можно открыть бутылку. Неплохо, верно?
Монолитное приложение — это единый большой блок кода, где все части тесно связаны друг с другом. Например, если ты разрабатываешь интернет-магазин, то в монолите всё будет в одном месте: и корзина покупок, и система оплаты, и поиск товаров. Казалось бы, удобно? Только на первый взгляд. Проблемы начинаются, когда нужно внести изменения. Допустим, ты решил обновить алгоритм поиска товаров. Трогаешь одну часть кода, а что-то неожиданно ломается в корзине или на странице оплаты. Напоминает игру в дженгу и бесконечные попытки поймать все баги.
Микросервисы же работают по-другому. Здесь каждая функция приложения — это отдельный сервис. Есть отдельный «сервис корзины», «сервис оплаты», «сервис поиска». Они общаются друг с другом через чётко определённые интерфейсы (обычно через API), но при этом остаются независимыми. Если нужно обновить алгоритм поиска, просто меняешь код в соответствующем сервисе. Остальные части приложения даже не замечают этого.
Основные принципы микросервисной архитектуры
Если микросервисы — это оркестр, то принципы, о которых мы сейчас поговорим, — это дирижёрская палочка. Без этого вся система превратится в хаотичное звучание, где барабанщик ушёл в нирвану, скрипач — в классику, а пианист вообще ушёл пить кофе. Чтобы всё работало слаженно и красиво, существуют некоторые правила, о которых сейчас и пойдёт речь.
Начнём с того, что уже частично затронули выше, а именно - независимость компонентов. Каждый микросервис — это самостоятельный механизм, который просто работает свою работу. Да, это немного, но это честная работа. Независимость позволяет командам разработчиков работать автономно. Ты можешь обновлять или чинить один сервис, не боясь, что где-то в другом месте что-то сломается.
Далее в списке идёт возможность развертывания отдельных модулей. В микросервисах ты можешь развернуть (или обновить) только один конкретный сервис, а не всё приложение целиком. Поиграем снова в имадженариум, вообразим в этот раз интернет-магазин. Нужно улучшить алгоритм рекомендаций товаров. В монолите вам пришлось бы обновить весь код приложения, протестировать его и переживать за возможные сбои. А с микросервисами ты просто выкатываешь обновление для «сервиса рекомендаций», и всё остальное продолжает работать как ни в чём не бывало. Звучит как сказка, ну… почти)
Чёткие границы ответственности. Каждый микросервис отвечает за свою чётко определённую задачу. Что также удобно при работе в команде, ведь видно сразу разделение обязанностей не только в программных компонентах, но и среди разработчиков. Чёткие границы ответственности делают систему понятной и предсказуемой. Если что-то пошло не так (например, клиент не может оформить заказ), то не нужно ковыряться в монолите кода, искать, где конкретно и кто писал эту функцию, достаточно понять, какой именно это микросервис.
Окей, это было просто понять, но вот как микросервисы между собой вообще работают? Они же не должны работать всё равно вместе. Ответ прост и состоит из трёх букв – API (а вы о чём подумали?). Микросервисы общаются друг с другом через API (Application Programming Interface) — это чётко определённый язык общения между сервисами. Он позволяет каждому сервису быть независимым и при этом эффективно взаимодействовать с другими.
Познакомились с базой, так, а что там по соотношениям плюсов к минусам? Ща разложим карты и на это.
Плюсы, минусы и вызовы микросервисной архитектуры
Конечно же, начнем с плюсов микросервисной архитектуры (а ведь их реально много). Вот они, сверху вниз:
Масштабируемость. В случае, если вашему приложению пришло время «подрасти», то с микросервисами достаточно просто добавить воды! Ладно, на самом деле увеличить мощность только необходимых сервисов или же написать новые, и не трогать остальные. Аналогично работает и с простыми обновлениями.
Независимость разработчиков по отдельности или же команд по отдельности (в зависимости от масштаба). Они могут работать над своим микросервисом, не мешая другим. Результат? Быстрее, чище и без лишнего стресса. Тут в целом все просто. Как и во всем, если разобраться)
Надёжность. Этого нам всем не хватает, а вот микросервесы умеют и делают. Если один сервис упал, остальные продолжают работать. Например, если в приложении временно недоступен сервис рекомендаций товаров (потому что кто-то где-то накосячил), пользователи всё равно смогут оформить заказ.
Плюсы простые, но безумно нужные. А теперь пришло время минусов.
Сложность управления. Чем больше микросервисов, тем сложнее ими управлять. Прикинь, если бы у тебя было 50 котиков: каждый требует внимания, ухода и еды. В итоге ты больше времени тратишь на организацию, чем на саму работу.
Сетевые задержки. Микросервисы взаимодействуют друг с другом через сеть, а это значит, что могут возникать задержки. Например, если «сервис корзины» медленно отвечает «сервису заказов», пользователь может подумать, что приложение зависло. А если сервисов много (как и предполагается), и если хотя бы некоторые из них медленно передают друг другу API, то скорости нам не видать.
Затраты… Всего... Каждый микросервис требует своих ресурсов: серверов, баз данных и инструментов мониторинга, людей и печенек. В итоге можно потратить больше денег на инфраструктуру, что не всегда возможно, да и вообще нужно, особенно в небольших проектах.
Сложность тестирования. Тестировать микросервисы сложнее, чем монолитное приложение. Это нужно убедиться не только в том, что каждый сервис работает правильно, но и в том, что они корректно взаимодействуют друг с другом. А это все тянет за собой все тот же пункт про затраты.
С глобальными минусами на этом все. Согласись, они были не столь очевидны. Немаловажным вопросом так же является вопрос «А когда микросервисы могут быть избыточными?»
Когда нужны микросервисы
Не всегда стоит бежать за модой и переходить на микросервисы только потому, что «все так делают, значит круто». Иногда это просто лишняя головная боль. И так, когда же?
Небольшие проекты или стартапы. Если проект небольшой (например, приложение для учёта личных расходов), то микросервисы будут избыточны. Также, если у команды банально нет опыта. Если команда никогда раньше не работала с микросервисами, переход на них может превратиться в кошмар из бесконечных багов и срывов сроков. Не того мы хотели ведь, правда? Исходя из статьи про затраты, не трудно догадаться, что если ресурсы ограничены, то микросервисы не наш выбор, ведь они требуют больше серверов, инструментов мониторинга и специалистов по DevOps, что не сочетается с маленькой командой и небольшим бюджетом.
Собственно, микросервисы – это очень крутая тема, но, как и все в этом мире, она хорошо работает только там, где нужна. Микросервисная архитектура – относительно новый тренд и как мы поняли, это очень классный тренд, помогающий увеличить эффективность разработки многократно на больших проектах. Следим за новшествами и дальше, кто знает, что изобретут уже завтра?