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

У них есть ряд преимуществ по сравнению с традиционными монолитными приложениями: быстрое развертывание, гибкое масштабирование, устойчивость к сбоям и многое другое.

Однако микросервисы не являются панацеей: у технологии есть особенности, способные превратить ее достоинства в недостатки. Расскажем, как разобраться, насколько они применимы к вашим приложениям, грамотно спланировать переход и каким принципам следовать при внедрении микросервисной архитектуры.

Кому не обойтись без микросервисов: как понять, что пора переносить на них ваш проект

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

  1. Численность команды

    Многие советуют посмотреть на размер вашей команды: если их порядка 10 человек и они справляются со всем приложением, зная его от и до — микросервисы, вероятно, только усложнят процесс разработки. Но если численность команды стремительно возрастает и все сложнее погружать вновь приходящих сотрудников в предметную область целиком — микросервисы выходят на первый план.

  2. Модульность приложения

    Стоит обратить внимание и на структуру самого приложения: если в нем 2-3 модуля, взаимодействующих друг с другом — в микросервисах также, скорее всего, нет необходимости. Но если модулей значительно больше и к ним обращается одновременно несколько фронтовых систем — микросервисы сильно облегчат вашу жизнь.

  3. Размер кода

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

  4. Время запуска

    Если время запуска монолитного приложения занимает порядка 30-40 минут — значительная часть времени разработчиков тратится на ожидание, отчего падает общая производительность. Это очевидный сигнал о необходимости микросервисов.

  5. Требования к ресурсам у разных компонентов приложения

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

  6. Критичность непрерывной доставки

    Допустим, вы разрабатываете мобильное приложение, от которого пользователи ожидают частого выхода новых интересных функций. Или работаете в государственном секторе, где необходимо в короткий срок реагировать на изменения в законах. Если для вас критична своевременность выхода обновлений — вам потребуется обеспечить непрерывную доставку своего приложения. А развертывание монолитных приложений может оказаться удручающе медленным.

  7. Трафик и масштабирование

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

Ниже рассмотрим рекомендуемые шаги по переходу на микросервисную архитектуру.

Как начать работу с микросервисами: best practices

Определите бизнес-потребности (или функции), которым будут соответствовать будущие сервисы. На одну задачу — один микросервис. Например, если вы развиваете интернет-магазин, бизнес-потребности могут быть такими: ведение каталога товаров, обработка заказов, платежи, учет пользователей.

При выделении функций старайтесь придерживаться принципа единой ответственности (SRP, single-responsibility principle), сформулированного Робертом С. Мартином: собрать вместе то, что изменяется по одинаковым причинам, и разделить то, что изменяется по разным.

Назначьте ответственную команду для каждой выделенной бизнес-функции. Каждая команда будет владеть соответствующим сервисом и станет экспертом в этой конкретной области.

Подберите технологический стек, оптимальный для решения задач каждого сервиса. Напоминаем, что набор используемых технологий может отличаться между микросервисами, но все же эксперты не рекомендуют использовать для приложения более 2-3 языков программирования без видимых на то причин — чтобы не усложнять взаимодействие между командами.

Проработайте связи между микросервисами. Особое внимание уделите проектированию будущих микросервисов и проработке связей между ними:

  1. Используйте инкапсуляцию, чтобы все ненужные детали реализации были скрыты, а открыто только то, что необходимо клиентам этого сервиса.
  2. Тщательно продумывайте протоколы взаимодействия. Желательно сохранять технологическую независимость API, используемых для обмена данными между сервисами. Присмотритесь к REST как к хорошему варианту интеграции по типу «запрос-ответ».
  3. Избегайте интеграций через общую базу данных. Рекомендуется использовать отдельное хранилище данных для каждого микросервиса. Если же другому сервису потребуются те же данные, лучше избегать прямого обращения к базе и настроить их получение через обращение к исходному сервису.

Помните, что неоптимально спроектированные сервисы обесценивают их применение. В дальнейшем изменить взаимодействие сервисов будет очень тяжело.

Настройте автоматическую сборку и развертывание ваших микросервисов. Используйте конвейеры CI/CD на базе любой доступной системы (Jenkins, TeamCity, Go и так далее).

Помните, что лучшими практиками считаются:

  • использование отдельной сборки для каждого микросервиса;
  • разворачивание одного микросервиса на одну операционную систему. Отдайте предпочтение контейнерной модели. Docker — одна из реализаций этой модели.

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

  1. Переборка (Bulkhead). В судостроении переборка является составной частью корабля, которая призвана защищать его помещения от поступления забортной воды. Благодаря переборкам поврежденная часть корабля может оказаться затоплена, но все оставшееся судно будет не тронуто. Также и в архитектуре приложения: переборки изолируют элементы приложения в пулы, чтобы в случае сбоя одного из них остальные продолжали функционировать. Пример — использование отдельного пула соединений для каждого из нижестоящих сервисов.
  2. Предохранитель (Circuits Breaker). Всем знакомы домашние предохранители, служащие для защиты электроприборов от скачков напряжения. Принцип действия шаблона тот же: предохранитель срабатывает после конкретного числа безответных вызовов нижестоящего сервиса. Пока он находится в таком состоянии — последующие запросы будут быстро возвращать ошибку. По истечении определенного времени клиент отправляет несколько запросов, чтобы определить работоспособность сервиса, и при получении достаточного числа успешных ответов — возвращает предохранитель в исходное состояние.

Используйте мониторинг. Из-за большого числа распределенных и технологически разнородных компонентов вам потребуется централизованное ведение логов и сбор статистики путем агрегации данных из отдельных сервисов. Освойте существующие для этих целей инструменты: ELK Stack, Graphite, Hystrix. Отслеживайте не только технические параметры хостов и время отклика сервисов, но и бизнес-показатели (количество пользователей, заказов и другие), изменение которых может также указывать на сбои.

Придерживайтесь принципа открытого исходного кода при разработке, используя системы контроля версий (Git, GitHub и прочие). Этот подход позволит вносить своевременные изменения в код даже в случае отсутствия его автора. А также станет дополнительным стимулом для написания более качественного кода.

Утвердите стандарты в отношении ведения кода, оформления API, обработки ошибок и придерживайтесь их. Это значительно повысит эффективность совместной работы нескольких команд над разными сервисами. Внедряйте Swagger и прочие инструменты, призванные помочь в ведении документации.

Чек-лист: как понять, что вы готовы к использованию микросервисов

Многие крупные компании с мировым именем добились успеха, используя в своих проектах микросервисную архитектуру. Среди них Amazon, Netflix, Twitter и множество других. Но, как и любую иную технологию, использовать ее необходимо осознанно, четко понимая, каких целей требуется достичь.

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

Советуем проверить все пункты из данного списка прежде, чем вы приступите к разработке своих первых микросервисов:

  • Возможность быстрой подготовки окружения. Убедитесь, что можете запустить новый сервер за считаные часы. Это требование станет критичным по мере увеличения числа сервисов. Оно прекрасно вписывается в облачную модель, но должно соблюдаться и без ее использования. Для быстрой подготовки вам потребуется высокий уровень автоматизации.
  • Наличие мониторинга для быстрого выявления проблем. При взаимодействии многочисленных слабосвязанных сервисов возрастает вероятность обнаружения в производственной среде сбоев, не выявленных при тестировании. Ваш мониторинг должен обеспечивать обнаружение ошибок и своевременное оповещение о них.
  • Возможность быстрого развертывания приложений. Вы должны быть готовы к частому развертыванию сервисов как в тестовой, так и в производственной средах. Поэтому без автоматизации опять-таки не обойтись. Используйте конвейеры развертывания (пайплайны), чтобы процесс не отнимал много времени и требовал минимального ручного вмешательства.
  • Внедрение культуры DevOps. Недостаточно освоить новые инструменты и технологии: значительные изменения необходимо провести и внутри вашей команды. До них необходимо донести основную идею DevOps-культуры: каждый участник команды несет ответственность за конечный продукт. Необходимо организовать тесное сотрудничество программистов, системных администраторов и тестировщиков на всех этапах разработки. Это позволит вам обеспечить высокую скорость выхода релизов и решения инцидентов.

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