Микросервис как сделать

Добавил пользователь Alex
Обновлено: 19.09.2024

Такой подход работает в маленьких командах. Но что будет, если проект будет намного сложнее? Давайте разбираться.

Проблемы монолитной разработки

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

  • регистрация в сервисе,
  • напоминание пароля,
  • создание нового списка задач,
  • управление списками,
  • создание новой задачи,
  • редактирование задачи,
  • удаление задачи.

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

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

Микросервисы — разбиваем программу на автономные части

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

  1. Каждая смысловая часть программы выносится в отдельный код, который делает что-то одно: получает данные от сервера, отправляет логин и пароль на проверку, даёт разрешение пользователю на вход и т. д.
  2. Каждая такая программа может получать и отправлять данные в каком-то формате. Благодаря этому программы могут обмениваться данными и управлять друг другом.
  3. Такие мини-программы и называются микросервисами.

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

Пример

Разобъём нашу программу из начала статьи на микросервисы:

Что такое микросервисы

Обратите внимание — у нас появились функциональные элементы, которых не было в исходной картинке: например отрисовка интерфейса, запрос данных от пользователя, отправка данных на сервер, запрос в БД.

Плюсы и минусы микросервисов

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

  • Каждый микросервис можно полностью заменить или переписать без потери качества для проекта, если у него будет тот же формат общения с другими микросервисами.
  • Если нужно, можно запустить одновременно несколько одинаковых микросервисов на разных компьютерах, чтобы повысить устойчивость и скорость работы приложения.
  • Если какой-то микросервис откажет, то чаще всего это не приводит к падению всего сервиса или программы. Ещё можно настроить автоматический перезапуск микросервиса после аварийного завершения.
  • Неважно, на каком языке написан микросервис, если он делает то, что нужно, и умеет общаться с другими. Например, для высокопроизводительных частей можно использовать С++, а для остальных — Java или Kotlin.
  • Можно постепенно наращивать возможности приложения, просто подключая новые микросервисы к системе.

Но и минусы у такого подхода тоже есть:

Пример: работа системы под нагрузкой

Допустим, у нас есть две версии одного и того же сервиса: один сделан единым кодом, второй — на микросервисах.

Пока нагрузка в рамках нормы, оба сервиса работают примерно одинаково:

Что такое микросервисы

Но если посетителей внезапно больше (например, отлично сработала рекламная кампания), то монолитный сервис может упасть под нагрузкой. Оказывается, базу данных не оптимизировали под такое количество запросов. А если у нас всё на микросервисах, то отдельная программа, которая за ними следит, увидит, что запросов стало слишком много, и запустит ещё несколько микросервисов с обработками запросов в базу данных:

Что такое микросервисы

Это что, теперь каждую программу нужно писать на микросервисах?

Нет, не обязательно. Микросервисы хороши только в сложных проектах или в сервисах с высокой нагрузкой.

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

5 лучших технологий для построения Microservices Architecture

Изучение

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

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

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

Что следует учитывать перед переходом на архитектуру микросервисов

Архитектура микросервисов формирует основу для продуктов, создаваемых такими компаниями, как Amazon, Netflix, Spotify и Uber. По сравнению с традиционным монолитным приложением микросервисы предлагают следующие преимущества:

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

Примечание. Микросервисы могут быть реализованы на разных языках программирования и могут использовать разные инфраструктуры.

Типичная микросервисная архитектура состоит из API или шлюза связи, обнаружения службы, службы и базы данных или кеша.

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

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

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

Docker и Kubernetes

Docker и Kubernetes

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

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

Docker и Kubernetes могут использоваться вместе, чтобы выступать в качестве гибкой основы для вашей системы на основе микросервисов, легко масштабируемой по мере увеличения рабочей нагрузки или наоборот.

Преимущества Docker для микросервисов

Docker — это облегченный вариант построения архитектуры микросервисов. Все компоненты микросервиса могут быть упакованы в образ Docker и оставаться изолированными от других микросервисов.

Docker упрощает развертывание вашего программного обеспечения, поскольку вам нужно только распространять образы Docker с помощью Dockerfiles.

С помощью Docker Compose несколько контейнеров можно скоординировать для создания целой системы микросервисов с контейнерами. Мы также можем использовать Docker Machine для установки среды Docker на сервере.

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

REST

Микросервисы должны взаимодействовать с другими микросервисами. Одним из инструментов, который можно использовать для этого, является REST (передача репрезентативного состояния). REST — это шаблон архитектурного проектирования для создания RESTful API.

Преимущества REST для микросервисов

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

Примечание. Pact — отличная среда для написания тестов интерфейса REST на языке программирования. В результате создается файл JSON, содержащий запросы REST и ожидаемые ответы.

Redis

Что такое Redis

Redis обычно используется в качестве первичной базы данных для вашего приложения, использующего Redis в постоянном режиме. Это также однопоточное приложение, поэтому для баз данных вам не нужно беспокоиться о блокировках записей. В этом шаблоне сущности хранятся с хэш-операциями. Redis обычно строится на основе фреймворков Spring Cloud или Spring Boot.

Преимущества Redis для микросервисов

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

Prometheus

Prometheus

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

Prometheus использует простой язык запросов, который составляет основу мониторинга задач. Сюда входят функции визуализации изменений и статистики.

Преимущества Prometheus для микросервисов

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

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

Consul

Consul

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

Консул очень гибкий. Благодаря интерфейсу DNS и шаблону Consul его можно использовать со многими технологиями. Это особенно важно в контексте микросервисов. Хотя в системе с самого начала может не потребоваться использование различных технологий, в долгосрочной перспективе будет выгодно иметь возможность интегрировать новые технологии.

Преимущества Consul для микросервисов

Настройка системы микросервисов с помощью Consul — отличный вариант для синхронной системы, поскольку ее инфраструктура отвечает типичным задачам синхронных микросервисов:

  • Обнаружение сервисов: эта функция покрывается Consul и полезна для интеграции новых технологий в ваши микросервисы.
  • Повышенная прозрачность: Consul полностью прозрачен и может использоваться без каких-либо зависимостей кода.
  • Конфигурация: Consul можно использовать для настройки микросервисов. Могут быть реализованы как обнаружение сервисов, так и их настройка.
  • Балансировка нагрузки: с помощью Consul DNS Consul прозрачно реализует балансировку нагрузки с помощью DNS-сервера.

Примечание: Consul написан на Go. Мониторинг и развертывание отличается от микросервисов Java.

Что учить дальше

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

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

Микросервисный подход в веб-разработке: micro frontends

В этой статье поговорим о микросервисном подходе в веб-разработке пользовательских интерфейсов.

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

Микросервисный подход в веб-разработке: micro frontends

Проблема и решение

Пользовательские интерфейсы в вебе продолжают развиваться. Подтверждение этому можно увидеть и на сайте:

Микросервисный подход в веб-разработке: micro frontends

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

  • время разработки в связи с высоким уровнем сложности кода;
  • время тестирования;
  • временной интервал между релизами.

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

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

Микросервисный подход в веб-разработке: micro frontends

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

Помимо этого, можно выделить и другие достоинства микросервисной архитектуры в сравнении с монолитной:

  • модульность;
  • уменьшение времени на тестирование;
  • сокращение времени на деплой и возможность делать это параллельно;
  • возможность горизонтального масштабирования команды.

А можно ли использовать микросервисный подход в веб-разработке пользовательских интерфейсов? Ответ: да! Можно и нужно! Именно такой подход и называют микрофронтенд (micro frontends).

Микрофронтенд (Micro frontends)

Микрофронтенд (micro frontend) — архитектурный подход, в котором независимые приложения собраны в одно большое приложение. Он дает возможность объединить в одном приложении разные виджеты или страницы, написанные разными командами с использованием разных фреймворков (см. рис. ниже).

Микросервисный подход в веб-разработке: micro frontends

Главные преимущества микрофронтенд-подхода — в разработке больших энтерпрайз-приложений:

  • модульная архитектура. Отдельные виджеты или страницы — это полностью независимые приложения;
  • скорость тестирования. Изменения в одном виджете или странице можно протестировать изолированно и только в этом приложении, не тратя времени на тестирование всего остального функционала;
  • параллельные деплойменты. Отдельные виджеты или страницы могут и должны деплоиться независимо.

Помимо очевидных достоинств такого подхода, у него есть и существенные недостатки:

  • увеличение общей сложности приложения;
  • дублирование кода. Каждое приложение разрабатывается отдельной командой, которая принимает свои технические решения. Это ведет к повторной загрузке одинаковых фреймворков, библиотек и общему дублированию кода, который мог быть использованным повторно;
  • JS-бандл монолитного приложения всегда будет меньше, чем совокупность бандлов в микрофронтенд-архитектуре;
  • возможные проблемы с кешированием и версионностью приложений;
  • глобальные переменные или CSS-стили — это вещи, о которых стоит забыть в микрофронтенд-архитектуре, если приложения полностью не изолированы.

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

Микросервисный подход в веб-разработке: micro frontends

К сожалению, пока не существует конкретной спецификации для построения микрофронтенд-архитектуры. Вот, пожалуй, самые доступные и простые способы и техники для построения микрофронтенд-приложений:

  • IFrames;
  • библиотека Tailor.js;
  • фреймворк single-spa.

Пройдемся по каждому из перечисленных подходов.

IFrames

IFrame — это давняя технология, которая, несмотря на всю свою неактуальность, дает возможность построить микрофронтенд-архитектуру. Используя IFrame, каждый отдельный виджет можно поместить в IFrame, который загружает нужное приложение. При использовании такого подхода вы, скорее всего, столкнетесь со следующими проблемами:

  • производительность;
  • сложность поддержки.

Крайне не рекомендую строить микрофронтенд-архитектуру, используя IFrame. Сегодня существуют другие способы сделать это проще и эффективней.

Библиотека Tailor.js

Здесь вы можете прочитать больше о самой библиотеке. Компания Zalando создала целую экосистему для построения микрофронтенд-архитектуры, и Tailor.js — это часть экосистемы. Особенность Tailor.js — то, что это пакет для Node.js, и ориентирован он на построение микрофронтенд-архитектуры с серверным рендерингом.

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

Single-spa

Основной и, по моему мнению, лучший подход в построении микрофронтенд-архитектуры — это фреймворк single-spa. Вот основные причины, по которым я советую выбрать single-spa:

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

Single-spa — это фреймворк, который дает возможность объединить разные приложения, независимо от используемой библиотеки или фреймворка, в одно целое. Под капотом single-spa набор существующих инструментов вместе с собственными решениями:

  • SystemJS — загрузчик модулей, который нужен для асинхронной загрузки отдельных приложений;
  • врапперы — single-spa предоставляет отдельные врапперы под каждый фреймворк, который создает обертку над приложением, нужную для интеграции и подключения отдельного приложения в общее single-spa;
  • API — single-spa предоставляет набор инструментов, которые нужны для коммуникации между отдельными приложениями, подписку на события и т. д.

Типичное приложение с использованием single-spa выглядит так:

Микросервисный подход в веб-разработке: micro frontends

А вот так выглядит коммуникация между отдельными элементами микрофронтенд-архитектуры, построенной с использованием single-spa:

Микросервисный подход в веб-разработке: micro frontends

Root Application — это корень приложения. Именно здесь происходит подключение sigle-spa как основного фреймворка, а также конфигурация SystemJS для корректной загрузки внешних приложений.

Каждое дочернее приложение для корректной интеграции должно предоставлять публичные методы bootstrap, mount, unmount, которые используются фреймворком single-spa для мануального бутстрэппинга приложения. Почти под каждый современный фреймворк существует готовый враппер, который упрощает эту задачу и автоматизирует некую часть процесса. На сайте single-spa можно найти список всех фреймворков, под которые существуют готовые врапперы.

Построить набор приложений с использованием микрофронтенд-подхода и single-spa можно как путем создания полностью всей инфраструктуры и приложений с нуля, так и на основе существующего приложения. Рассмотрим примеры того, как это выглядит, создавая набор полностью новых приложений с использованием React.js и Angular 8.

Конфигурация билда для React.js под single-spa представлена здесь.

Используя существующий враппер single-spa для React.js, мы создаем интерфейс с методами bootstrap, mount, unmount, где соответственно описываем, как должно бутстрэппиться наше приложение. Враппер помогает инкапсулировать внутреннюю имплементацию и создать API для правильного подключения в single-spa фреймворка.

Похожим образом это выглядит и для Angular 8.

Так же, как и в случае с React.js, мы предоставляем интерфейс для ручного бутстрэппинга приложения на Angular 8.

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

Две главные части, на которые стоит обратить внимание:

  • script-тег, в котором нужно описать маппинг названия приложения, на адрес, с которого single-spa будет подгружать amd-модуль для этого приложения;
  • script-тег, где нужно непосредственно зарегистрировать приложение с помощью метода registerApplication. Здесь нужно указать адрес, при переходе на который system.js будет загружать соответствующий модуль.

Как можно увидеть, Root Application — простой HTML-файл с основными конфигурациями для загрузки других приложений. В одном микрофронтенд-приложении можно зарегистрировать множество микроприложений. Если при регистрации приложения в 3-м параметре метода registerApplication указать просто /, такое приложение будет загружаться для каждого доступного адреса. Именно такой подход желательно использовать для создания навигационной панели или частей приложения, которые являются общими и не должны загружаться повторно при переходе между приложениями.

Полностью рабочий пример того, как это работает, можно найти в моем GitHub-репозитории.

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

Нам, разработчикам, далеко не всегда приходится создавать приложения с нуля. Single-spa дает возможность полностью использовать существующие приложения как элементы микрофронтенд-архитектуры, будь то Root Application или асинхронно загружаемые микроприложения.

Если из существующего приложения нужно создать Root Application, тогда в первую очередь нужно в index.html подключить библиотеки для single-spa и добавить все необходимые для загрузки других микроприложений конфигурации. После того как ваш index.html стал Root Application в single-spa, можно приступить к настройке остальной части приложения для корректной работы в single-spa-архитектуре так, как это описано в предыдущем абзаце.

Проблемы и недостатки

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

На этапе конфигурации проблемы, с которыми вы столкнетесь, будут самые разнообразные, поэтому запаситесь терпением 😉

Кроме сложной конфигурации, выделим проблемы, которые могут возникнуть при построении микрофронтенд-архитектуры с использованием single-spa:

  • кеширование микроприложений. Без правильной стратегии по кешированию микроприложения, как и Root Application, будут кешироваться в браузере и игнорировать любые новые изменения, которые будут релизнуты;
  • дебаггинг. Если что-то не работает, дебаггинг без дополнительных конфигураций и надстроек может быть довольно тяжелым процессом, так как вам придется дебажить не приложения, а отдельные amd-модули без сорс мап;
  • общий размер приложения вместе со всеми асинхронными микроприложениями увеличится, в сравнении с монолитным подходом;
  • общая производительность микрофронтенд-приложения будет ниже, чем у монолита;
  • повторение кода. Повторная загрузка кода — как библиотек, так и целых фреймворков — ведет к ухудшению быстродействия всего приложения, а не только отдельной страницы. Single-spa дает возможность шарить зависимости между приложениями, но помните: чем больше у вас зависимостей, библиотек, компонент, которые шарятся между приложениями, тем больше ваша микрофронтенд-архитектура похожа на монолитную;
  • SEO-оптимизация. Загрузка отдельных приложений вместе с бутстрэппингом полностью проходит на клиенте, что значительно усложняет SEO-оптимизацию. Single-spa не поддерживает серверный рендеринг, для добавления поддержки можно использовать связку single-spa + Tailor.js.

Выводы

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

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

Один из частых вопросов: можно ли использовать single-spa для миграции с одного фреймворка на другой (например, с AngularJS на Angular 2+)? Можно, но не нужно: практически всегда есть более легкий и нативный способ миграции, который требует меньше конфигурационной работы и который будет работать быстрее.

Почему вам не нужны микросервисы главное изображение

Этот текст не объясняет, что такое микросервисы и как работает такая архитектура. Но если вы впечатлены историей успеха микросервисов и надеетесь на них как на панацею в своем приложении — этот материал написан для вас. Этот текст о сложностях, с которыми вы столкнетесь при использовании микросервисов, а также об ответственности разработчиков при выборе инструментов для работы.

Примечание — Это адаптированный перевод статьи STOP!! You don’t need Microservices Эбина Джона, архитектора сетей и веб-разработчика. Повествование ведётся от лица автора оригинала.

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

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

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

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

Ваше приложение действительно настолько велико, что его можно разбить на микросервисы?

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


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

Отдельные компоненты приложения действительно нуждаются в масштабировании?

Объясню на примере. Допустим, product owner пришел к вам с идеей сделать новый сервис — систему управления персоналом (HRMS) для организаций, численность сотрудников которых превышает 10 тысяч человек. Энтузиаст технологий внутри вас сразу предложит решение — микросервисная архитектура. Дальше происходит примерно следующее:


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

Есть ли у вас транзакции, связанные с услугами?

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

Cервисы REST не имеют состояния по определению и не должны участвовать в транзакциях, которые проходят по нескольким сервисам. В мире высокой производительности двухфазная фиксация (2PC) — ненужное зло. А протокол SAGA добавит еще один уровень сложности, к которому вы можете быть не готовы.

Итак, можно ли добиться того, чтобы транзакции охватывали разные службы? Конечно! Но стоит ли делать цепочку действий поверх сервисов без состояния (stateless)? Вероятно, нет.

Сервисам необходимо часто общаться друг с другом?

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

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

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

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

И еще немного фактов

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

Стоимость развертывания. Микросервисы — это распределенные системы с молекулярной структурой, а распределение имеет свою цену. Если монолит можно развернуть на одной виртуальной машине или в контейнере, то каждой службе в микросервисной структуре (по крайней мере, в идеальном мире) требуется отдельная виртуальная машина или контейнер. Их объем меньше, чем у монолита, но, скорее всего, они обойдутся дороже даже без учета стоимости обслуживания.

Команда DevOps. Без команды DevOps поддерживать и контролировать микросервисы не получится, а найм таких специалистов может и помочь, и навредить компании. С одной стороны, DevOps — это широко распространенное и проверенное операционное решение. Но если компания небольшая, найм таких специалистов скорее принесет убытки, чем сделает организацию более прогрессивной.

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

Устаревшая база кода. Давайте будем честны — большинство из нас каждый день работает с устаревшей базой кода. Быстро развитие технологий двигает нас вперед, но в то же время они еще больше изолируют нас от legacy-кода. Вы уверены, что только что разработанный фреймворк на RabbitMQ, будет хорошо работать с устаревшим приложением на IBM AIX?

Проблемы при отладке. Каждая служба будет иметь собственный набор файлов журнала для анализа. Чем больше сервисов, тем больше файлов.

Выше я пытался ответить на вопрос, стоит ли использовать микросервисы. Мой ответ — определенно нет.

Итоги

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

Я не стану осуждать вашу доверчивость, если вы внедрили микросервисы пять лет назад. Тогда было другое время и все, что мы можем сделать сейчас — честно рассказать о минусах этой архитектуры. К 2021 году сообщество достаточно обожгло об нее руки. Теперь ясно, что безосновательно внедряя архитектуру микросервисов, вы превратите свой плохой код в плохую инфраструктуру.

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

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

Читайте также: