[Java, Микросервисы] О клиенте и сервере в микросервисной архитектуре
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Согласно устоявшемуся в индустрии мнению, работа старших разработчиков и архитекторов ПО во многом состоит из поиска компромиссов между преимуществами и недостатками тех или иных решений и выделения "достаточно хороших решений" для поставленных задач.Когда мы задались вопросом перехода на микросервисную архитектуру, мы столкнулись с некоторым количеством подобных трейд-оффов. Проведя ряд экспериментов и отвязавшись от специфических для нашего продукта бизнес-требований, мы попытались сформулировать вопросы, которые могут встать перед любой командой разработки, безотносительно к требованиям к продукту. Ну и, конечно, дать на них ответы - никто не любит вопросы без ответов.В качестве прикладного дополнения к рассуждениям мы разработаем несколько Proof of Concept, сопроводим их разработку краткими пояснениями и приложим исходный код PoC.Для нас "родным" стеком является Java 8 и Spring Boot 2, так что приложенные демки будут написаны на основе этих технологий с изрядными вкраплениями Spring Cloud. Мы также постараемся предложить несколько обособленных типовых решений для задач, которые, как нам показалось, могут в перспективе возникнуть перед разработчиками.
О насМы - подразделение группы компаний "Миландр", занимающееся разработкой и поддержкой IoT-платформы "ИНФОСФЕРА". Этот продукт включает в себя комплекс решений для ЖКХ, умного дома, электросетевой энергетики и промышленных предприятий. Мы собираем данные с различных приборов (счетчиков, датчиков, камер, домофонов, умных устройств), позволяем клиентам оперировать этими данными (в том числе, с использованием алгоритмов ML), настраивать пользовательские сценарии автоматизации для обработки данных, а также осуществлять удаленное управление приборами.
Интерфейс "ИНФОСФЕРА Диспетчерская"Для кого эта статья
- Для новичков, желающих ознакомиться с основными компонентами Spring Cloud и принципами, лежащими в основе микросервисной архитектуры.
- Для разработчиков и архитекторов, планирующих переход к микросервисной архитектуре.
- Для разработчиков и архитекторов, желающих пополнить коллекцию типовых решений и почитать про грабли, на которые можно наступить при первом использовании Spring Cloud.
Про микросервисыМикросервисам и Spring Cloud на Хабре уже посвящено множество статей, которыми, отчасти, мы вдохновлялись и которые хотели бы дополнить в тех моментах, где чувствовали недостаточное раскрытие темы.Концепция микросервисной архитектуры достаточно молода, но мы уже успели за 5-6 лет посмотреть, как она прошла все этапы Gartner Hype Cycle.Мы видели, как в 2015-м году люди восторгались новым подходом, видели и отторжение технологии в 2016-м, и теперь, после дозревания технологии и отношения к ней, можем видеть прагматические рассуждения, с трезвыми рассуждениями и подробным описанием плюсов и минусов.Что касается необходимости использования такой архитектуры, для нас при реализации нескольких новых проектов возникла необходимость в адаптации к возрастающим нагрузкам. Возможность выборочного масштабирования отдельных компонентов системы и послужила главным аргументом для рассмотрения возможности перехода на новую архитектуру.Про Spring CloudSpring Cloud - набор инструментов, позволяющих организовать работу Spring-based приложений в соответствии с принципами микросервисной архитектуры.Статьи, описывающие использование Spring Cloud
- Отличная статья от @sqshq с уклоном в практические аспекты создания микросервисного приложения, с подробными описаниями действий и отличными примерами.
- Простейшее демо, показывающее, как запустить Eureka Server и подключить к нему клиенты.
Небольшое уточнение для первой работы со Spring CloudОбращаем внимание на не совсем привычный механизм указания зависимостей от Spring Cloud. После создания проекта с зависимостями из Spring Cloud через Spring Initializr в глаза сразу бросается, что starters из Spring Cloud не наследуются из родительского pom-файла, как это происходит со стартерами Spring Boot, а приносятся через dependency management:
<properties>
<spring-cloud.version>2020.0.3</spring-cloud.version>
</properties>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
1. Так что же за вопросы?В нашем случае на первый план вышли вопросы, касающиеся принципов организации клиентского приложения и наладки его взаимодействия с серверной стороной. Сложности добавляет тот факт, что все эти вопросы достаточно плотно переплетены между собой. Будем разбираться.ВопросВарианты решенияВыбор принципа рендеринга веб-страницClient-side rendering, Server-side rendering, MixedХранение и выдача интерфейса на клиентЕдиная точка, микрофронтенды, несколько точек-страницПротоколы взаимодействия клиента и сервера, а также сервисов друг с другомБрокер, HTTP, WS, смесьНеобходимость Service DiscoveryЗависит от использования HTTPМы намеренно оставляем за пределами подробного рассмотрения (ограничившись упоминаниями, по крайней мере, в рамках данной статьи) следующие вопросы:
- Использование Spring Security для обеспечения безопасности использования приложения,
- Распределенные транзакции для обеспечения согласованности баз данных разных микросервисов,
- Балансировка нагрузки для адаптируемости отдельных компонентов к возрастанию нагрузки,
- Боевое развертывание, пока говорим преимущественно о процессе разработки. Некоторые недостатки предлагаемых подходов могут быть нивелированы за счет грамотного проектирования и администрирования.
1.1 Рендеринг страницПервый вопрос, который хотелось бы рассмотреть, относится к выбору подхода к рендерингу страниц.Под этими словами подразумевается, где будет формироваться HTML-документ для дальнейшего его использования браузером. На текущем этапе развития технологий в основном предлагается использовать клиентский рендеринг (Client-side rendering, CSR) и серверный рендеринг (Server-side rendering, SSR).Рассмотрим коротко суть каждого из подходов.Серверный рендеринг
Данный подход предполагает формирование HTML-страницы (возможно, с каким-то изначальным набором данных, предоставляемых в рамках запроса пользователя к странице) на сервере. Дальнейшее взаимодействие пользователя с интерфейсом может осуществляться посредством исполнения загружаемого JS-кода или полным обновлением всей HTML-страницы при выполнении того или иного действия.Преимущества
- С точки зрения пользователя это позволяет быстро получить отрисованную страницу (и даже содержательную отрисовку, если сервер перед выдачей страницы сразу подставляет в нее данные).
Недостатки
- После отрисовки страница может еще некоторое время находиться в неоперабельном состоянии, до подготовки JS-кода к исполнению;
- Без ухищрений в клиентском коде может потребоваться полное обновление страницы для обновления данных.
Технологии:
- JSP;
- Thymeleaf;
- Mustache;
- + ваши любимые JS-библиотеки;
Клиентский рендеринг
Данный подход, напротив, предполагает формирование страницы на клиенте посредством исполнения JS-кода. Например, так поступает React при работе через JSX, формируя содержимое страницы из кусков разметки, возвращаемой из компонентов.Преимущества
- Почти одновременно происходит отрисовка страницы и наступает готовность к взаимодействию.
Недостатки
- В скорости отрисовки проигрывает серверному рендерингу, поскольку JS необходимо загрузить, а затем исполнить на клиенте. Страница будет отрисована и готова к работе только по окончании работы всего необходимого для отрисовки JS-кода.
СсылкиХорошая обзорная статья (картинки взяты из нее же)1.2 Протоколы взаимодействия клиента и сервера, а также сервисов друг с другомДля микросервисной архитектуры в качестве механизма обмена данными между сервисами зачастую рекомендуют использовать событийно-ориентированную архитектуруДанный подход к разработке информационных систем предписывает обеспечивать общение сервисов друг с другом посредством обмена сообщения через специализированный middleware-софт, предназначенный для работы по принципам PUB/SUB. PUB/SUB обеспечивает слабую связанность приложений-источников сообщений и приложений-потребителей сообщений.Мы и раньше использовали механизм обмена событиями между приложениями, но в весьма ограниченном круге задач: так передавались показания от приборов и отправлялись команды на приборы.Здесь мы вплотную подошли к вопросу: как следует организовать взаимодействие сервисов друг с другом? Как определить, следует ли в конкретной ситуации использовать событийный подход или следует использовать типичные для HTTP запрос-ответ? Порассуждаем.Событийный подход хорошо показывает себя, когда:
- стороне, публикующей событие, не требуется ответ (реакция на это событие);
- есть несколько сервисов, заинтересованных в получении события;
- существует потребность в сохранении события в топике (для случая использования Kafka или другого персистентного брокера сообщений) для возможности потом его прочитать из топика.
С другой стороны, HTTP лучше подходит в ситуациях:
- когда требуется получить ответ на запрос;
- когда требуется выполнить синхронную операцию;
- когда не нужно привносить дополнительную сложность в систему, ограничившись синхронным обращением одного сервиса к другому.
Из этого набора фактов следует, что комбинировать события и HTTP-запросы - уместная практика. При этом нужно четко осознавать, для каких задач какой тип взаимодействия использовать.Случай “внешнего” клиентаТут хотелось бы обсудить вопрос адресации при обращении к сервисам из внешнего клиента. Для выполнения HTTP-запроса к сервису клиенту необходимо знать адрес этого сервиса. В целом, существует несколько типовых решений этой проблемы:
- Хардкод адресов в клиентском коде (негибко и очень сложно поддерживать в боевом окружении, отметаем);
- Параметризация клиентского кода (негибко, отметаем);
- Использование паттерна Service Discovery для клиента (подробнее о Service Discovery можно прочесть ниже) и отправка HTTP запросов напрямую к сервисам;
- Использование паттерна API gateway для проксирования всех запросов к backend-сервисам через единую точку входа. Подробнее об API gateway можно прочесть ниже;
- Если же основное взаимодействие между сервисами строится на основе событий и брокера сообщений, можно попытаться подключить клиентское приложение напрямую к брокеру. Хотя современные технологии и позволяют это сделать, такая архитектура привносит серьезные проблемы с безопасностью, и потому далее не рассматривается.
Из пяти вариантов для рассмотрения остаются два:
- Service Discovery;
- API Gateway.
Service Discovery для клиентских приложений - жизнеспособный подход, обеспечивающий возможность менять конфигурацию адресов сервисов на лету. Проблема в том, что он предполагает прямые обращения к сервисам, что вынуждает выставлять все сервера, с которыми взаимодействует клиент, наружу из защищенных сетей. Такой подход приводит к возникновению большого количества направлений атаки, поэтому противоречит хорошим практикам безопасности.Еще одна сложность может возникнуть вследствие недопустимости прямого доступа клиента к брокеру сообщений. Если для обмена данными между сервисами будет использоваться исключительно событийная модель, сервисам все равно потребуется HTTP API, чтобы внешний клиент мог взаимодействовать с ними.С другой стороны, API Gateway выступает единой точкой входа клиентов в защищенную сеть, поэтому, будучи единственным сервисом, доступным снаружи, выступает единственным направлением атаки для злоумышленника, не проникшего в защищенную сеть. Следует отметить, что по тем же причинам API Gateway также является и единой точкой отказа, выход которой из строя сделает невозможным взаимодействие клиентов с сервером.Другая сильная сторона API Gateway заключается в возможности выступать шлюзом для внешних запросов даже в том случае, когда внутри сервисной сети используется обмен данными только через брокер. Нам не удалось найти готовых реализаций инструментов, которые могли бы производить "перекладывание" запроса к backend в брокер, но подобная логика может быть без труда реализована и посредством обычных Web-контроллеров.Существует еще один вариант архитектуры - введение дополнительного слоя сервисов 1-го уровня, способных принимать запросы от API Gateway по HTTP и перекладывать их в брокер. Такой подход позволяет и не вводить HTTP API для всех сервисов и сохранить “чистоту” API Gateway, не привнося туда логику работы с брокером.Еще одно преимущество API Gateway над подходом Service Discovery может быть получено при использовании WebSocket для полнодуплексного обмена данными между клиентом и сервером. Например, может возникнуть задача уведомлять клиентское приложение о происходящих в системе событиях. Источниками таких событий могут выступать несколько backend-сервисов. Вместо поддержания нескольких WS-соединений с такими сервисами клиент может поддерживать одно соединение с одной точкой, предоставляющей возможность пересылки таких уведомлений через WS. API Gateway - неплохой кандидат для решения этой задачи.Исходя из приведенных рассуждений, мы сформулировали для себя следующие выводы:
- Смешение событий и HTTP-запросов - допустимая практика;
- Запрос от клиента к API Gateway следует направлять по HTTP;
- Во внутренней сети для поиска адресов сервисов для последующего выполнения HTTP-запросов следует использовать Service Discovery. Он же может служить заделом для масштабирования;
- Использовать HTTP для межсервисного взаимодействия на ранней стадии переработки системы - допустимая практика, обеспечивающая простоту и быстрое построение работоспособной системы.
Spring Cloud GatewayСсылки
- Концепт API Gateway
- Официальный гайд по Spring Cloud Gateway
- Гайд от Baeldung по Spring Cloud Gateway
Документация по java-конфигурации Spring Cloud Gateway:
Spring Cloud Gateway принимает входящие внешние запросы, проверяет свои правила маршрутизации и, в случае нахождения подходящего для пришедшего запроса правила, перенаправляет запрос к одному из сервисов.Данный сервис предназначен для упрощения взаимодействия клиента, находящегося во внешней сети, с сервисами, расположенными во внутренней backend-сети.ИспользованиеПо сути, для начала работы со Spring Cloud Gateway нужно сделать лишь две вещи:
- Добавить зависимость в ClassPath;
- А Определить бин типа org.springframework.cloud.gateway.route.RouteLocator и добавить его конфигурацию;
ИЛИ
Б Прописать конфигурацию в файле application.properties/yaml
Пример
На этапе разработки мы решили остановиться на java-конфигурации. Это позволило опробовать более тонкие варианты конфигурации API-gateway. Однако, вместе с тем, в промышленной эксплуатации этот вариант привносит и ограничения, не позволяя изменять конфигурацию "на лету" (например, с использованием Spring Cloud Config), вынуждая менять код приложения, исполняемого в боевом окружении, и, как следствие, требуя пересборки приложения при необходимости внести изменения в конфигурацию шлюза.Мы попытались предложить несколько типовых решений для конфигурации Spring Cloud Gateway, которые могли бы быть полезны сообществу.Пример 1: Меняем request path при помощи регулярного выражения. Запрос /google/hello приведет к обращению по адресу с параметром http://google.com/search?q=hello.
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder
.routes()
.route(r -> r
.path("/google/**")
.filters(gatewayFilterSpec -> gatewayFilterSpec.rewritePath("/google/(?<appendix>.*)", "/search?q=${appendix}"))
.uri("http://google.com"))
.build();
}
Пример 2: Отрезаем от path 1 блок. Запрос /yandex/hello/123 будет перенаправлен на http://yandex.ru/hello/123
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder
.routes()
.route(r -> r
.path("/yandex/**")
.filters(gatewayFilterSpec -> gatewayFilterSpec.stripPrefix(1))
.uri("[http://yandex.ru](http://yandex.ru)"))
.build();
}
Пример 3: Формируем URI для перенаправления, вычленяя адрес сервиса из path запроса.
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder
.routes()
.route(r -> r
.path("/service/**")
.filters(gatewayFilterSpec -> gatewayFilterSpec.changeRequestUri(serverWebExchange -> {
ServerHttpRequest originalRequest = serverWebExchange.getRequest();
URI oldUri = serverWebExchange.getRequest().getURI();
UriComponentsBuilder newUri = UriComponentsBuilder.fromUri(oldUri)
.host(originalRequest.getPath().subPath(3, 4).toString() + ".com") // 0,1,2,3 - /service/<serviceName>,
.port(null)
.replacePath(originalRequest.getPath().subPath(4).toString());
return Optional.of(newUri.build().toUri());
}))
.uri("http://ignored-URI")) // Этот URI игнорируется
.build();
}
Пример 4: Прописываем route с минимальным приоритетом. Запросы по адресам, не предусмотренным в других route, будут пересылаться по адресу localhost:8090.
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder
.routes()
.route(r -> r
.order(Integer.MAX_VALUE)
.path("/**")
.uri("[http://localhost:8090](http://localhost:8090)"))
.build();
}
1.3 Хранение интерфейса и его выдача на клиентВ рамках решения задачи передачи интерфейса для исполнения на клиент также существует несколько вариантов действия.МикрофронтендыПо сути - это продолжение идеи микросервисов и на UI. Некоторые микросервисы, помимо выполнения серверных задач, также имеют в своей зоне ответственности части пользовательского интерфейса, которые могут быть отданы на клиент для использования.
Оригинальное изображение - https://techrocks.ru/2018/09/19/prepare-your-skill-...ends/Объединение компонентов может осуществляться как на клиенте, так и на сервере.
Преимущества
- Гибко - позволяет развивать UI разных компонентов независимо друг от друга.
- Продолжение идеи независимого развертывания - позволяет исключать микросервисы из продакшена, что будет приводить к исчезновению лишь отдельных компонентов со страницы. Например, упал сервис N, его кусочки интерфейса недоступны, а все остальное - живее живых. Круто.
- Возможность использовать разные технологии для разных блоков интерфейса. Если не уходить в занудство на тему однообразия технологий и простоты поддержки, следует признать, что это все же выглядит скорее преимуществом.
Недостатки
- Сложно организовать совместную работу с UI. Подход требует серьезной дисциплины, например, в части выдерживания единых стилей. Как следствие, нужны компетенции в клиентской разработке.
- Накладные расходы на формирование интерфейса из кусочков. Как трудовые, так и вычислительные.
- Подход молодой, и его нужно глубоко и аккуратно изучать.
Технологии
Единая точка хранения интерфейсаСледующий вариант предписывает хранение всего, что нужно для работы пользовательского интерфейса, в одном сервисе. В качестве такого сервиса может существовать как обособленный сервис, так и сервис, совмещенный по функционалу с другим сервисом.Вариант 1 - Выделенный UI-сервисВ backend-сети выделяется отдельный сервис, единственная задача которого - хранить и отдавать по запросу пользовательский интерфейс.Преимущества
- Логическая обособленность интерфейсного кода и страниц от остального кода приложения.
Недостатки
- Необходимость создания и администрирования отдельного сервиса.
Технологии
- Spring Web + JSP/Thymeleaf как простейший пример для минимальной реализации.
Вариант 2 - UI GatewayВыше мы уже упоминали паттерн API Gateway. Существует практика расширения этого шлюза до UI Gateway - шлюза с функционалом хранения и раздачи страниц и клиентского кода.Преимущества
- Меньшее количество сервисов, чуть большая простота администрирования, не нужно прописывать дополнительные роутинги на UI.
Недостатки
- Как мы помним, API Gateway - единая точка отказа системы. Даже при наличии его реплицированных экземпляров в эксплуатации обновление такого шлюза для обновления UI выглядит достаточно рискованной операцией.
ТехнологииSpring Web + JSP/Thymeleaf как простейший пример для минимальной реализации.Вариант 3 - Page UI-сервисКонцепция похожа на предыдущую с той лишь разницей, что единый UI-сервис в данном подходе разбит на несколько сервисов, каждый из которых отвечает за одну или несколько страниц.Преимущества
===========
Источник:
habr.com
===========
Похожие новости:
- [Программирование, Алгоритмы] Найти подстроку в строке
- [JavaScript, Программирование, Node.JS] Как управлять несколькими потоками в Node JS (перевод)
- [JavaScript, API, Стандарты связи] Консорциум Всемирной паутины принял стандарт Web Audio в качестве официального
- [Конференции, Интервью] Как запустить первый микровервис: доклад Java Meeting Point
- [JavaScript] Первая программа для семилетки
- [JavaScript, Программирование, Тестирование веб-сервисов, Машинное обучение] В закладки: репозитории с книгами, шпаргалками, ресурсами по дизайну и не только (перевод)
- [Программирование, Java] Создание самодостаточных исполняемых JAR (перевод)
- [JavaScript, Программирование, Алгоритмы, Обработка изображений, Машинное обучение] Как мы создали Web приложение для определения лиц и масок для Google Chrome (часть 2) (перевод)
- [Микросервисы] Лучшие фреймворки для микросервисов (перевод)
- [JavaScript, Учебный процесс в IT, Удалённая работа] История о том, как я иду к должности JS разработчика через обучение на курсах в Skillbox
Теги для поиска: #_java, #_mikroservisy (Микросервисы), #_arhitektura (Архитектура), #_spring, #_spring_cloud, #_mikroservisy (Микросервисы), #_blog_kompanii_milandr (
Блог компании Миландр
), #_java, #_mikroservisy (
Микросервисы
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:44
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Согласно устоявшемуся в индустрии мнению, работа старших разработчиков и архитекторов ПО во многом состоит из поиска компромиссов между преимуществами и недостатками тех или иных решений и выделения "достаточно хороших решений" для поставленных задач.Когда мы задались вопросом перехода на микросервисную архитектуру, мы столкнулись с некоторым количеством подобных трейд-оффов. Проведя ряд экспериментов и отвязавшись от специфических для нашего продукта бизнес-требований, мы попытались сформулировать вопросы, которые могут встать перед любой командой разработки, безотносительно к требованиям к продукту. Ну и, конечно, дать на них ответы - никто не любит вопросы без ответов.В качестве прикладного дополнения к рассуждениям мы разработаем несколько Proof of Concept, сопроводим их разработку краткими пояснениями и приложим исходный код PoC.Для нас "родным" стеком является Java 8 и Spring Boot 2, так что приложенные демки будут написаны на основе этих технологий с изрядными вкраплениями Spring Cloud. Мы также постараемся предложить несколько обособленных типовых решений для задач, которые, как нам показалось, могут в перспективе возникнуть перед разработчиками. О насМы - подразделение группы компаний "Миландр", занимающееся разработкой и поддержкой IoT-платформы "ИНФОСФЕРА". Этот продукт включает в себя комплекс решений для ЖКХ, умного дома, электросетевой энергетики и промышленных предприятий. Мы собираем данные с различных приборов (счетчиков, датчиков, камер, домофонов, умных устройств), позволяем клиентам оперировать этими данными (в том числе, с использованием алгоритмов ML), настраивать пользовательские сценарии автоматизации для обработки данных, а также осуществлять удаленное управление приборами. Интерфейс "ИНФОСФЕРА Диспетчерская"Для кого эта статья
<properties>
<spring-cloud.version>2020.0.3</spring-cloud.version> </properties> ... <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
Данный подход предполагает формирование HTML-страницы (возможно, с каким-то изначальным набором данных, предоставляемых в рамках запроса пользователя к странице) на сервере. Дальнейшее взаимодействие пользователя с интерфейсом может осуществляться посредством исполнения загружаемого JS-кода или полным обновлением всей HTML-страницы при выполнении того или иного действия.Преимущества
Данный подход, напротив, предполагает формирование страницы на клиенте посредством исполнения JS-кода. Например, так поступает React при работе через JSX, формируя содержимое страницы из кусков разметки, возвращаемой из компонентов.Преимущества
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder .routes() .route(r -> r .path("/google/**") .filters(gatewayFilterSpec -> gatewayFilterSpec.rewritePath("/google/(?<appendix>.*)", "/search?q=${appendix}")) .uri("http://google.com")) .build(); } @Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder .routes() .route(r -> r .path("/yandex/**") .filters(gatewayFilterSpec -> gatewayFilterSpec.stripPrefix(1)) .uri("[http://yandex.ru](http://yandex.ru)")) .build(); } @Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder .routes() .route(r -> r .path("/service/**") .filters(gatewayFilterSpec -> gatewayFilterSpec.changeRequestUri(serverWebExchange -> { ServerHttpRequest originalRequest = serverWebExchange.getRequest(); URI oldUri = serverWebExchange.getRequest().getURI(); UriComponentsBuilder newUri = UriComponentsBuilder.fromUri(oldUri) .host(originalRequest.getPath().subPath(3, 4).toString() + ".com") // 0,1,2,3 - /service/<serviceName>, .port(null) .replacePath(originalRequest.getPath().subPath(4).toString()); return Optional.of(newUri.build().toUri()); })) .uri("http://ignored-URI")) // Этот URI игнорируется .build(); } @Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder .routes() .route(r -> r .order(Integer.MAX_VALUE) .path("/**") .uri("[http://localhost:8090](http://localhost:8090)")) .build(); } Оригинальное изображение - https://techrocks.ru/2018/09/19/prepare-your-skill-...ends/Объединение компонентов может осуществляться как на клиенте, так и на сервере. Преимущества
=========== Источник: habr.com =========== Похожие новости:
Блог компании Миландр ), #_java, #_mikroservisy ( Микросервисы ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:44
Часовой пояс: UTC + 5