Изучение Нового Весеннего Облачного Врата
1. обзор
В этой статье мы рассмотрим основные особенности проектаSpring Cloud Gateway, нового API, основанного на Spring 5, Spring Boot 2 и Project Reactor.
Этот инструмент предоставляет готовые механизмы маршрутизации, часто используемые в приложениях микросервисов, как способ скрыть несколько служб за одним фасадом.
Для объяснения паттерна Gateway без проекта Spring Cloud Gateway ознакомьтесь с нашимprevious article.
2. Обработчик маршрутизации
Ориентируясь на запросы маршрутизации, Spring Cloud Gateway перенаправляет запросы в сопоставление обработчика шлюза, которое определяет, что следует делать с запросами, соответствующими определенному маршруту.
Давайте начнем с быстрого примера того, как обработчик шлюза разрешает конфигурации маршрута с помощьюRouteLocator:
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("r1", r -> r.host("**.example.com")
.and()
.path("/example")
.uri("http://example.com"))
.route(r -> r.host("**.example.com")
.and()
.path("/myOtherRouting")
.filters(f -> f.prefixPath("/myPrefix"))
.uri("http://othersite.com")
.id("myOtherID"))
.build();
}
Обратите внимание, как мы использовали основные строительные блоки этого API:
-
Route – основной API шлюза. Он определяется заданным идентификатором (ID), пунктом назначения (URI) и набором предикатов и фильтров.
-
Predicate –Predicate – из Java 8, который используется для сопоставления HTTP-запросов с использованием заголовков, методов или параметров.
-
Filter – стандартная пружинаWebFilter
3. Динамическая маршрутизация
Как иZuul, Spring Cloud Gateway предоставляет средства для маршрутизации запросов к различным службам.
Конфигурация маршрутизации может быть создана с использованием чистой Java (RouteLocator, как показано в примере в разделе 2.1) или с помощью конфигурации свойств:
spring:
application:
name: gateway-service
cloud:
gateway:
routes:
- id: example
uri: example.com
- id: myOtherRouting
uri: localhost:9999
4. Фабрики маршрутизации
Spring Cloud Gateway сопоставляет маршруты с помощью инфраструктуры Spring WebFluxHandlerMapping.
Он также включает в себя множество встроенных фабрик предикатов маршрутов. Все эти предикаты соответствуют различным атрибутам HTTP-запроса. Множество фабрик предикатов маршрутов можно объединять с помощью логических «и».
Сопоставление маршрутов может применяться как программно, так и через файл свойств конфигурации с использованием другого типа фабрик предикатов маршрутов.
4.1. Before Фабрика предикатов маршрутов
Фабрика предикатов маршрутаBefore принимает один параметр: adatetime. Этот предикат соответствует запросам, которые происходят до текущегоdatetime:
spring:
cloud:
gateway:
routes:
- id: before_route
uri: http://example.com
predicates:
- Before=2017-09-11T17:42:47.789-07:00[America/Alaska]
Конфигурация Java может быть представлена как:
//..route definition
.route(r -> r.before(LocalDateTime.now().atZone(ZoneId.systemDefault()))
.id("before_route")
.uri("http://example.com")
4.2. Между фабрикой предикатов маршрута
Фабрика предикатов маршрутаBetween принимает два параметра:datetime1, иdatetime2. Этот предикат соответствует запросам, которые происходят послеdatetime1 (включительно) и доdatetime2 (исключая). Параметрdatetime2 должен стоять послеdatetime1:
spring:
cloud:
gateway:
routes:
- id: between_route
uri: http://example.com
predicates:
- Between=2017-09-10T17:42:47.789-07:00[America/Alaska], 2017-09-11T17:42:47.789-07:00[America/Alaska]
И конфигурация Java выглядит следующим образом:
ZonedDateTime datetime1 = LocalDateTime.now().minusDays(1).atZone(ZoneId.systemDefault());
ZonedDateTime datetime2 = LocalDateTime.now().atZone(ZoneId.systemDefault())
//..route definition
.route(r -> r.between(datetime1, datetime2))
.id("between_route")
.uri("http://example.com")
4.3. Header Фабрика предикатов маршрутов
Фабрика предикатов маршрутаHeader принимает два параметра: имя заголовка и регулярное выражение. Этот предикат соответствует заголовку, соответствующему регулярному выражению:
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://example.com
predicates:
- Header=X-Request-Id, \d+
Конфигурация Java может быть представлена как:
//..route definition
.route(r -> r.header("X-Request-Id", "\\d+")
.id("header_route")
.uri("http://example.com")
4.4. Host Предикатный фактор маршрута
Фабрика предикатов маршрутаHost принимает один параметр: шаблон имени хоста. Шаблон представляет собой шаблон в стиле муравья с «.» В качестве разделителя.
Этот предикат соответствует заголовкуHost с заданным шаблоном:
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.com
predicates:
- Host=**.example.com
Вот альтернатива конфигурации Java:
//..route definition
.route(r -> r.host("**.example.com")
.id("host_route")
.uri("http://example.com")
4.5. Method Фабрика предикатов маршрутов
Фабрика предикатов маршрутовMethod принимает один параметр: метод HTTP для сопоставления:
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://example.com
predicates:
- Method=GET
Конфигурация Java может быть представлена как:
//..route definition
.route(r -> r.method("GET")
.id("method_route")
.uri("http://example.com")
4.6. Path Фабрика предикатов маршрутов
Фабрика предикатов маршрутаPath принимает один параметр: шаблон SpringPathMatcher:
spring:
cloud:
gateway:
routes:
- id: path_route
uri: http://example.com
predicates:
- Path=/articles/{articleId}
Конфигурация Java:
//..route definition
.route(r -> r.path("/articles/"+articleId)
.id("path_route")
.uri("http://example.com")
4.7. Query Фабрика предикатов маршрутов
Фабрика предикатов маршрутаQuery принимает два параметра: обязательный параметр и необязательное регулярное выражение:
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.com
predicates:
- Query=articleId, \w
И конфигурация Java:
//..route definition
.route(r -> r.query("articleId", "\w")
.id("query_route")
.uri("http://example.com")
4.8. RemoteAddr Фабрика предикатов маршрутов
Фабрика предикатов маршрутовRemoteAddr принимает список (минимум 1) строк CIDR-нотации, например192.168.0.1/16 (где 192.168.0.1 - это IP-адрес, а 16 - маска подсети):
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: http://example.com
predicates:
- RemoteAddr=192.168.1.1/24
И соответствующая конфигурация Java:
//..route definition
.route(r -> r.remoteAddr("192.168.1.1/24")
.id("remoteaddr_route")
.uri("http://example.com")
5. Фабрики WebFilter
Фильтры маршрутов позволяют модифицировать входящий HTTP-запрос или исходящий HTTP-ответ.
Spring Cloud Gateway включает в себя множество встроенных фабрик WebFilter.
5.1. AddRequestHeaderWebFilter Завод
Фабрика WebFilterAddRequestHeader принимает параметр имени и значения:
spring:
cloud:
gateway:
routes:
- id: addrequestheader_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- AddRequestHeader=X-SomeHeader, bael
Вот соответствующая конфигурация Java:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.addRequestHeader("X-TestHeader", "rewrite_request"))
.uri("http://example.com")
.id("addrequestheader_route")
5.2. AddRequestParameter Фабрика WebFilter
Фабрика WebFilterAddRequestParameter принимает параметр имени и значения:
spring:
cloud:
gateway:
routes:
- id: addrequestparameter_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- AddRequestParameter=foo, bar
Соответствующая конфигурация Java:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.addRequestParameter("foo", "bar"))
.uri("http://example.com")
.id("addrequestparameter_route")
5.3. AddResponseHeader Фабрика WebFilter
Фабрика WebFilterAddResponseHeader принимает параметр имени и значения:
spring:
cloud:
gateway:
routes:
- id: addrequestheader_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- AddResponseHeader=X-SomeHeader, Bar
Соответствующая конфигурация Java:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.addResponseHeader("X-SomeHeader", "Bar"))
.uri("http://example.com")
.id("addresponseheader_route")
5.4. Автоматический выключательWebFilter Заводской
Hystrix используется как фабрика WebFilter автоматического выключателя и принимает единственный параметр имени, который является именем команды Hystrix:
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- Hystrix=someCommand
Соответствующая конфигурация Java:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.hystrix("some-command"))
.uri("http://example.com")
.id("hystrix_route")
5.5. RedirectTo Фабрика WebFilter
Фабрика WebFilterRedirectTo принимает статус и параметр URL. Статус должен быть HTTP-кодом перенаправления 300, например, 301:
spring:
cloud:
gateway:
routes:
- id: redirectto_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- RedirectTo=302, http://foo.bar
И соответствующая конфигурация Java:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.redirect("302","http://foo.bar"))
.uri("http://example.com")
.id("redirectto_route")
5.6. RewritePath Фабрика WebFilter
Фабрика WebFilterRewritePath принимает параметр регулярного выражения пути и параметр замены. Это использует регулярные выражения Java, чтобы переписать путь запроса.
Вот пример конфигурации:
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.com
predicates:
- Path=/articles/**
filters:
- RewritePath=/articles/(?.*), /$\{articleId}
Конфигурация Java может быть представлена как:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.rewritePath("(?.*)", articleId))
.uri("http://example.com")
.id("rewritepath_route")
5.7. RequestRateLimiter Фабрика WebFilter
RequestRateLimiter WebFilter Factory принимает три параметра:replenishRate, capacity, иkeyResolverName..
-
replenishRate– представляет, сколько запросов в секунду вы хотите, чтобы пользователь мог выполнять
-
capacity– определяет допустимую пропускную способность
-
keyResolverName - это имя bean-компонента, реализующего интерфейсKeyResolver
Интерфейс KeyResolver позволяет подключаемым стратегиям получать ключ для ограничения запросов:
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- RequestRateLimiter=10, 50, userKeyResolver
Конфигурация Java может быть представлена как:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.requestRateLimiter().configure(c -> c.setRateLimiter(myRateLimiter)))
.uri("http://example.com")
.id("requestratelimiter_route")
6. Поддержка Spring Cloud DiscoveryClient
Spring Cloud Gateway можно легко интегрировать с библиотеками Service Discovery и Registry, такими как Eureka Server и Consul:
@Configuration
@EnableDiscoveryClient
public class GatewayDiscoveryConfiguration {
@Bean
public DiscoveryClientRouteDefinitionLocator
discoveryClientRouteLocator(DiscoveryClient discoveryClient) {
return new DiscoveryClientRouteDefinitionLocator(discoveryClient);
}
}
6.1. LoadBalancerClient Фильтр
LoadBalancerClientFilter ищет URI в свойстве атрибута обмена, используяServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR.
Если URL-адрес имеет схемуlb (например,lb://example-service), он будет использовать Spring CloudLoadBalancerClient для преобразования имени(i.e., example-service) в фактический хост и порт.
Неизмененный исходный URL-адрес помещается в атрибутServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR.
7. мониторинг
Spring Cloud Gateway использует Actuator API, широко известную библиотеку Spring-Boot, которая предоставляет несколько готовых сервисов для мониторинга приложения.
После установки и настройки Actuator API функции мониторинга шлюза могут быть визуализированы путем доступа к конечной точке/gateway/.
8. Реализация
Теперь мы создадим простой пример использования Spring Cloud Gateway в качестве прокси-сервера с использованием предикатаpath.
8.1. зависимости
Spring Cloud Gateway в настоящее время находится в репозитории этапов, в версии 2.0.0.RC2. Эту версию мы и здесь используем.
Чтобы добавить проект, воспользуемся системой управления зависимостями:
org.springframework.cloud
spring-cloud-gateway
2.0.0.RC2
pom
import
Далее мы добавим необходимые зависимости:
org.springframework.boot
spring-boot-actuator
org.springframework.boot
spring-boot-starter-webflux
org.springframework.cloud
spring-cloud-starter-gateway
8.2. Реализация кода
А теперь создаем простую конфигурацию маршрутизации в файлеapplication.yml:
spring:
cloud:
gateway:
routes:
- id: example_route
uri: http://example.com
predicates:
- Path=/example/
management:
endpoints:
web:
exposure:
include: "*'
И код приложения Gateway:
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
После запуска приложения мы можем получить доступ к url:“http://localhost/actuator/gateway/routes/example_route”, чтобы проверить всю созданную конфигурацию маршрутизации:
{
"id":"example_route",
"predicates":[{
"name":"Path",
"args":{"_genkey_0":"/example"}
}],
"filters":[],
"uri":"http://example.com",
"order":0
}
Мы видим, что относительный url:“/example” настроен как маршрут, ** поэтому при нажатии на url“http://localhost/example” мы будем перенаправлены на «http://example.com», как было настроено в нашем примере.
9. Заключение
В этой статье мы рассмотрели некоторые функции и компоненты, которые являются частью Spring Cloud Gateway. Этот новый API предоставляет готовые инструменты для поддержки шлюза и прокси.
Представленные здесь примеры можно найти в нашемGitHub repository.