Изучение Нового Весеннего Облачного Шлюза

Изучение Нового Весеннего Облачного Врата

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.