Микросервисы в вебе: неправильные пчелы или проблема в монолите

SKTeam.ru
SKTeam.ru

Микросервисная архитектура извечная тема споров на многих IT-конференциях. Как правильно внедрить в рабочий процесс и какой важный момент в процессе запуска может облегчить работу в дальнейшем, рассказывает Владимир Скибин, главный разработчик и руководитель компании SKTeam

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

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

Самым простым примером может служить отправка почты с сайта, которая выполняется не в основном потоке приложения, а в отдельном сервисе. Задачей этого вспомогательного сервиса как раз является разгрузить основной поток приложения от рутинных задач и позволить ему заниматься основной логикой. Этот своеобразный заместитель у начальника принимает задачу отправить письмо и сам занимается его отправкой. Основная часть приложения всегда может поинтересоваться статусом отправки (это опциональная функциональность, реализации которой многие не придают значения). После выполнения своей задачи сервис оповестит о том, что он все сделал записью в базе об успешном или провальном выполнении. Громким названием “сервис” он, так сказать, “не достоин” называться, поскольку у него только одна функция – поэтому такие части приложения и называли микросервисы.

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

Немного истории

Каждый, кто писал приложения, как в вебе так и standalone, сталкивался с проблемой разделения ответственности между модулями. Те, кто использует полноценно в своей практике принципы разработки SOLID понимали, что переход от приложения, где все работает в едином целом, к приложению, которое можно разделить на несколько черных ящиков, определить между ними протоколы (правила) взаимодействия – неизбежен.

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

Следствием оказалось то, что эти самые части, на которые разделился продукт можно писать совершенно в разных подходах или вообще на разных языках программирования. Например, часть на PHP, часть на C++, а основную часть вообще на NodeJS.

Рост популярности

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

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

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

На самом деле – это очень тонкая грань. Важно проанализировать и понять, на какие и на сколько микросервисов нужно делить приложение. И тут нужно выбрать только важные, без которых работа приложения будет невозможна. Также необходимо правильно обработать все ошибки. Если микросервис отвалился – то все остальные части должны функционировать в своем полном объеме, но при запросе данных с упавшего – указывать, что нет возможности с ним связаться.

К примеру, если не работает микросервис отправки почты, то из-за этого не должно падать основное приложение. Пусть его задачи копятся в неком реестре, а после восстановления работоспособности, он все свои задачи постепенно выполнит.

А что с тестированием?

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

Единственной проблемой, которая может возникнуть – e2e-тестирование. Для его полноценного проведения все микросервисы должны быть запущены и быть работоспособными. Хотя с другой стороны – также целью написания e2e тестов выступает еще и моделирование поведения случаев, когда что-то не работает.

В итоге

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

  • Изначально все можно писать в монолите, таким образом выйдет первый прототип быстрее.
  • По мере необходимости автономные модули выносить в микросервисы. Изначально можно их “вешать” на http сервис и связь с ними организовывать также.
  • По мере роста количества микросервисов – внедрять системы доставки сообщений, такие как RabitMQ, ActiveMQ, NATS. Эти системы как раз выполняют роль реестров необработанных сообщений.
  • И на каждом этапе отпочковывания очередного микросервиса тестировать точки отказа, а при необходимости внедрять системы кэшированных ответов, чтобы падение отдельного модуля-микросервиса не было крахом всего приложения.

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

Владимир Скибин, руководитель SKTeam

Начать дискуссию