Пишем Java веб-приложение на современном стеке. С нуля до микросервисной архитектуры. Часть 3
Мы создали и запустили два микросервиса. Теперь понадобится то, что их свяжет и будет маршрутизировать запросы пользователя на каждый из них.
18К открытий19К показов
В прошлых частях мы успешно спроектировали и запустили два микросервиса: сервис BookStore и сервис аутентификации/авторизации.
Теперь мы можем расположить каждый из них на отдельном инстансе (например в AWS EC2), но в таком случае они будут выглядеть не как одно целое для конечного потребителя. Далее при развитии архитектуры количество сервисов будет только увеличиваться, и нам понадобится что-то, что свяжет наши сервисы и будет маршрутизировать запросы пользователя на каждый из них. Для этих целей используют шаблон проектирования API Gateway, который позволяет реализовать единую точку входа в нашу систему, и перенаправляет запросы на нужный микросервис.
Существует множество реализаций Api Gateway — например, Kong, Gravitee, Krakend и т.д. Мы же воспользуемся решением для экосистемы Spring Cloud — Spring Cloud Gateway.
Spring Cloud Gateway представляет собой Spring-Boot приложение, которое позволяет настраивать маршрутизацию в yaml-конфиге или в коде приложения, а также расширять логику путём написания своего кода. Реализуем схему, при которой все запросы на эндпоинт /registration
и /login
будут перенаправляться на сервис авторизации, /help
будет вести на сайт spring, а остальные запросы будут маршрутизироваться в BookStore. Запускать всё вместе будем на одном инстансе на разных портах (аналогично реализуется на нескольких инстансах).
Начнём с генерации gradle-проекта на start.spring.io. После добавления компонента Gateway должен получиться следующий build.gradle:
Код Main-класса:
На этом всё, остается сконфигурировать маршруты для наших запросов в соответствии со схемой. Как я говорил, конфигурацию можно писать кодом или в yaml-файле, который и будем использовать вместо application.properties
:
В секции routes
указываются правила для обработки входящий запросов. В данном случае правило предписывает все запросы на эндпоинт /books
перенаправлять на http://localhost:8080
. То есть Gateway, получив такой запрос, сделает вызов своим http-клиентом на http://localhost:8080
и полученный ответ вернёт пользователю.
Добавим теперь правила для сервиса авторизации, продолжив список в yaml-конфигурации (обращая внимание на табуляции, так как лишний tab может привести к ошибке, и приложение не запустится):
Здесь у нас появились фильтры — сущности, позволяющие модифицировать запрос. Полное описание фильтров можно найти в документации. Как можно догадаться из названия, RewritePath модифицирует путь запроса. Приходящие запросы на эндпоинты /registration
и /login
будут перенаправлены на сервис авторизации на эндпоинты /auth
и /auth/token
соответственно.
Добавим ещё одно правило, которое будет возвращать 302 Redirect
на страницу с руководствами Spring:
Отправив запрос на /help
, пользователь будет получать 302, и браузер будет редиректить на страницу https://spring.io/guides
.
Запустим все три приложения (на портах 8080, 8081 и 80) и попытаемся сделать запросы через Api Gateway.
Регистрация
Аутентификация
Получение данных
Переадресация
С помощью фильтров можно также добавлять необходимые заголовки в запросы, менять тело запроса и ответа, добавлять дополнительные параметры в запрос и так далее.
Отдельно хочется выделить фильтры CircuitBreaker и RequestRateLimiter, которые используются в высоконагруженных системах. RequestRateLimiter необходим для ограничания количества запросов, при превышении порога которых, пользователю будет возвращаться 429 Too Many Requests
.
CircuitBreaker используется, чтобы при падении одного из сервисов Gateway не продолжал спамить этот сервис, не давая ему корректно подняться. В этом случае Gateway сразу будет возвращать ошибку и перенаправит поток сообщений только тогда, когда сервис успешно поднимется.
Входящие в состав Spring Cloud Gateway стандартные предикаты и фильтры в большинстве случаев покрывают все потребности. Однако, если вам понадобится реализовать что-то более сложное, то придется самостоятельно написать код. Особенностью фреймворка является его реактивность — он построен на основе Spring WebFlux и Project Reactor. Требуется некоторая подготовка и понимание принципов реактивного программирования.
Стоит отметить, что обычно Api Gateway также используется для терминирования https. То есть защищённое соединение устанавливается между пользователем и Gateway, а дальше трафик на внутренние сервисы идёт уже по протоколу http, что избавляет от необходимости работы с сертификатами на сотнях микросервисах.
Код проекта доступен на GitHub.
18К открытий19К показов