От монолита к микросервисам: проксирование запросов

Описание подхода к проксированию запросов через монолитную систему при переходе на микросервисную архитектуру.

В статье «От монолита к микросервисам» приведен пример того, как и для чего перестать развивать легаси-монолит, выделяя новую функциональность в отдельный сервис и направляя трафик посредством API Gateway на этот сервис.

API Gateway

Эта схема проста и понятна до тех пор, пока мы не столкнемся с реальностью.

Рассмотрим пример. Монолитная система, посредством кототой можно получить чертеж любой части самолета в нескольких форматах (точная геометрия, легковесная pdf). Права доступа определяются на основе роли пользователя, страны и множества других параметров, например: Export Control на основе ITAR, ECCN и EAR-кодов), тип/формат документа, тип детали, да еще и в связке с номером самолета, владельцем и так далее. Логика сложная и запутанная.

Первый «микросервис» может быть предельно простым, каким он и должен быть. Скорее всего его напишет один или пара энтузиастов и он будет делать что-то тривиальное.

Идея хорошая, появляются знания об организации процесса поставки, разбивается стена страха неизвестности, появляется мотивация, тут может появиться проксирующий запросы шлюз и энтузиасты предлагают вынести в отдельные микросервисы что-нибудь посложнее. Сервис, возвращающий точную геометрию, например. Ведь это сулит невероятные выгоды: независимая поставка, использование подходящих технологий, горизонтальное масштабирование при росте нагрузки, удобная балансировка…пока не выясняется, что «права доступа определяются на основе…», «все обращения должны быть зафиксированы…». Казалось бы — пусть API Gateway этим и займется, безопасность — это сквозная функциональность до определенного уровня, но логика ровным слоем размазана по всему монолиту, её вычленение займет уйму времени.

Как быть?

Предусловия

С помощью первых, простых сервисов, компания учится выполнению предусловий для микросервисной архитектуры, сформулированных Мартином Фаулером:

  • Быстрое создание новых окружений
  • Простой, но не примитивный, мониторинг
  • Быстрый и надежный процесс поставки

Phil Calçado (Meetup, в прошлом DigitalOcean и SoundCloud) расширил список предусловий, добавив следующие:

  • Быстрое расширение/создание хранилищ данных
  • Легкий доступ к границам систем
  • Аутентификация/авторизация
  • Стандартизированный RPC

И мы получаем первую проблему: получить доступ извне во внутреннюю сеть оказывается не так просто.

Не масштабируется!

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

Что делать?

Предлагается на первых порах использовать в качестве прокси сам монолит:

Монолит в качестве Proxy

При этом среди задач технического долга появляется «Рефакторинг авторизации и аутентификации» с целью выделения этой функциональности в отдельный пакет и последующим выделением в отдельный сервис, после чего можно переходить с целевой картинке с реализацией сквозной функциональности по безопасности на уровень API Gateway.

На какое-то время всё станет сложнее: при изменении сервисов может потребоваться поставка и монолитного приложения.

О чем не забыть?

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

  • Логирование (отдельные части приложения могут писать логи в собственном формате в различные файлы.
  • Механизмы инструментирования кода и сбора метрик
  • Уведомления об ошибках
  • Трассировка запросов (сквозная идентификация бизнес-транзакции)
  • Методы проверки работоспособности (HealthCheck)
  • Внешнее конфигурирование

Со временем все это следует привести к единому стандарту и сделать частью микросервисного фреймворка, общего для всех сервисов. Как это согласуется с тем, что каждый сервис можем использовать свои собственные технологии? Java, Ruby, Go? Под каждый язык придется поддерживать свою реализацию, обеспечивающую стандартное поведение: если мы договорились, что пишем логи в определенном формате в syslog, то все сервисы следуют этим договорённостям.

Подводя итог

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

Share