Пишем Java веб-приложение на современном стеке. С нуля до микросервисной архитектуры. Часть 3 |
||
МЕНЮ Главная страница Поиск Регистрация на сайте Помощь проекту Архив новостей ТЕМЫ Новости ИИ Голосовой помощник Разработка ИИГородские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Искусственный интеллект Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Нейронные сети начинающим Психология ИИ Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Творчество ИИ Техническое зрение Чат-боты Авторизация |
2022-01-20 13:56 В прошлых частях мы успешно спроектировали и запустили два микросервиса: сервис BookStore и сервис аутентификации/авторизации. Теперь мы можем расположить каждый из них на отдельном инстансе (например в AWS EC2), но в таком случае они будут выглядеть не как одно целое для конечного потребителя. Далее при развитии архитектуры количество сервисов будет только увеличиваться, и нам понадобится что-то, что свяжет наши сервисы и будет маршрутизировать запросы пользователя на каждый из них. Для этих целей используют шаблон проектирования API Gateway, который позволяет реализовать единую точку входа в нашу систему, и перенаправляет запросы на нужный микросервис. Существует множество реализаций Api Gateway — например, Kong, Gravitee, Krakend и т.д. Мы же воспользуемся решением для экосистемы Spring Cloud — Spring Cloud Gateway. Spring Cloud Gateway представляет собой Spring-Boot приложение, которое позволяет настраивать маршрутизацию в yaml-конфиге или в коде приложения, а также расширять логику путём написания своего кода. Реализуем схему, при которой все запросы на эндпоинт Начнём с генерации gradle-проекта на start.spring.io. После добавления компонента Gateway должен получиться следующий build.gradle: plugins { id 'org.springframework.boot' version '2.6.2' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' repositories { mavenCentral() } ext { set('springCloudVersion', "2021.0.0") } dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-gateway' testImplementation 'org.springframework.boot:spring-boot-starter-test' } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" } } test { useJUnitPlatform() } Код Main-класса: @SpringBootApplication public class SpringDemoApigatewayApplication { public static void main(String[] args) { SpringApplication.run(SpringDemoApigatewayApplication.class, args); } } На этом всё, остается сконфигурировать маршруты для наших запросов в соответствии со схемой. Как я говорил, конфигурацию можно писать кодом или в yaml-файле, который и будем использовать вместо server: port: 80 spring: cloud: gateway: httpclient: ssl: useInsecureTrustManager: true routes: - id: bookstore uri: http://localhost:8080 predicates: - Path=/books/** В секции Добавим теперь правила для сервиса авторизации, продолжив список в yaml-конфигурации (обращая внимание на табуляции, так как лишний tab может привести к ошибке, и приложение не запустится): - id: registration uri: http://localhost:8081 predicates: - Path=/registration filters: - RewritePath=/registration, /auth - id: token uri: http://localhost:8081 predicates: - Path=/login filters: - RewritePath=/login, /auth/token Здесь у нас появились фильтры — сущности, позволяющие модифицировать запрос. Полное описание фильтров можно найти в документации. Как можно догадаться из названия, RewritePath модифицирует путь запроса. Приходящие запросы на эндпоинты Добавим ещё одно правило, которое будет возвращать - id: help uri: https://spring.io/guides predicates: - Path=/help filters: - RedirectTo=302, https://spring.io/guides Отправив запрос на Запустим все три приложения (на портах 8080, 8081 и 80) и попытаемся сделать запросы через Api Gateway. Регистрация curl --location --request POST 'http://localhost/registration' --header 'Content-Type: application/json' --data-raw '{ "clientId": "admin", "clientSecret": "password" }' HTTP/1.1 200 OK Content-Type: text/plain;charset=UTF-8 Date: Thu, 06 Jan 2022 10:15:00 GMT content-length: 10 Registered Аутентификация curl --location --request POST 'http://localhost/login' --header 'Content-Type: application/json' --data-raw '{ "clientId": "admin", "clientSecret": "password" }' HTTP/1.1 200 OK transfer-encoding: chunked Content-Type: application/json Date: Thu, 06 Jan 2022 10:16:20 GMT { "token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJib29rc3RvcmUiLCJzdWIiOiJhZG1pbiIsImlzcyI6ImF1dGgtc2VydmljZSIsImV4cCI6MTY0MTQ2NDQ4MCwiaWF0IjoxNjQxNDY0MTgwfQ.qTVmUmfG4tro_D9ui7iSrBGZBi0Z0ob653kKV2vjjp0" } Получение данных curl --location --request GET 'http://localhost/books' --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJib29rc3RvcmUiLCJzdWIiOiJhZG1pbiIsImlzcyI6ImF1dGgtc2VydmljZSIsImV4cCI6MTY0MTQ2NDQ4MCwiaWF0IjoxNjQxNDY0MTgwfQ.qTVmUmfG4tro_D9ui7iSrBGZBi0Z0ob653kKV2vjjp0' HTTP/1.1 200 OK transfer-encoding: chunked Content-Type: application/json Date: Thu, 06 Jan 2022 10:17:58 GMT [ { "id" : 1, "author" : "Joshua Bloch", "title" : "Effective Java", "price" : 54.99 }, { "id" : 2, "author" : "Kathy Sierra", "title" : "Head First Java", "price" : 12.66 }, { "id" : 3, "author" : "Benjamin J. Evans", "title" : "Java in a Nutshell: A Desktop Quick Reference", "price" : 28.14 } ] Переадресация curl --location --request GET 'http://localhost/help' HTTP/1.1 302 Location: https://spring.io/guides content-length: 0 С помощью фильтров можно также добавлять необходимые заголовки в запросы, менять тело запроса и ответа, добавлять дополнительные параметры в запрос и так далее. Отдельно хочется выделить фильтры CircuitBreaker и RequestRateLimiter, которые используются в высоконагруженных системах. RequestRateLimiter необходим для ограничания количества запросов, при превышении порога которых, пользователю будет возвращаться CircuitBreaker используется, чтобы при падении одного из сервисов Gateway не продолжал спамить этот сервис, не давая ему корректно подняться. В этом случае Gateway сразу будет возвращать ошибку и перенаправит поток сообщений только тогда, когда сервис успешно поднимется. Входящие в состав Spring Cloud Gateway стандартные предикаты и фильтры в большинстве случаев покрывают все потребности. Однако, если вам понадобится реализовать что-то более сложное, то придется самостоятельно написать код. Особенностью фреймворка является его реактивность — он построен на основе Spring WebFlux и Project Reactor. Требуется некоторая подготовка и понимание принципов реактивного программирования. Стоит отметить, что обычно Api Gateway также используется для терминирования https. То есть защищённое соединение устанавливается между пользователем и Gateway, а дальше трафик на внутренние сервисы идёт уже по протоколу http, что избавляет от необходимости работы с сертификатами на сотнях микросервисах. Код проекта доступен на GitHub. Источник: m.vk.com Комментарии: |
|