Spring Cloud Gateway в яме

Spring Cloud

помещение

В последнее время проводится реконструкция старой системы.После завершения реконструкции в новую систему необходимо внедрить службу шлюза в качестве приспособления и прокси для интерфейса между новой системой и старой системой. Раньше многие шлюзовые приложения использовалиSpring-Cloud-Netfilxна основеZuul1.xверсия реализована, но учитываяZuul1.xИтерация остановлена, используется более традиционная реализация блокировки (B)IO + многопоточность, по факту производительность не очень. Позже команда Spring просто самостоятельно переработала набор компонентов шлюза, что мы и рассмотрим на этот раз.Spring-Cloud-Gateway.

Введение

Spring Cloud Gateway зависит отSpring Boot 2.0, Spring WebFluxProject Reactor. Многие знакомые библиотеки синхронизации (например,Spring-DataиSpring-Security) и режим синхронного программирования вSpring Cloud Gatewayне применяется во фреймворке, поэтому лучше сначала прочитать документацию трех фреймворков, упомянутых выше.

Spring Cloud Gatewayзависит отSpring BootиSpring WebFluxпредоставляется на основеNettyсреду выполнения, он не построен как WAR-пакет и не работает на традиционномServletв контейнере.

имя собственное

  • Маршрут: Маршрут является основным компонентом шлюза. Он определяется идентификатором, целевым URI, набором предикатов и набором фильтров. Если агрегация предикатов оценивается как true, маршрут сопоставляется.
  • Предикат: введен на основе функционального программирования в Java 8.java.util.Predicate. При использовании предикатного (агрегационного) суждения входными параметрами являютсяServerWebExchangeТип, который позволяет разработчикам сопоставлять произвольные параметры HTTP-запросов, такие как заголовки HTTP-запросов, параметры HTTP-запросов и т. д.
  • Фильтр (Filter): использует указанныйGatewayFilterзавод созданGatewayFilterНапример, запрос (параметры) или ответ (параметры) могут быть изменены до или после отправки запроса вниз по течению.

фактическиFilterтакже включеныGlobalFilter, но в официальной документации это не упоминается.

Принцип работы

s-c-g-e-1.png

клиент дляSpring Cloud Gatewayсделать запрос, еслиGateway Handler MappingМодуль обрабатывает текущий запрос и, если он соответствует целевой конфигурации маршрутизации, запрос будет переадресован наGateway Web Handlerмодуль.Gateway Web HandlerКогда модуль отправляет запрос, он пропускает запрос через цепочку фильтров, соответствующую запросу. Причина, по которой фильтры разделены пунктирными линиями на приведенном выше рисунке, заключается в том, что логика обработки фильтра может выполняться до или после отправки прокси-запроса. всеpreЗапрос прокси не будет создан (и отправлен) до тех пор, пока не будет выполнен тип фильтра, а когда запрос прокси создан (и отправлен), всеpostтип фильтра будет выполнен.

См. рисунок выше, если приходит внешний запрос и попадает в цепочку фильтров, то левая часть пунктираpreтип фильтра, запрос проходит первымpreтип фильтра, который затем отправляется в целевую прокси-службу. Целевая прокси-служба отвечает на запрос, и ответ снова проходит через цепочку фильтров, то есть цепочку фильтров справа от пунктирной линии.postтип фильтра.

Обратите внимание, что если соответствующий порт маршрутизации явно не указан в конфигурации маршрутизации, будут использоваться следующие порты по умолчанию:

  • Протокол HTTP, использующий порт 80.
  • Протокол HTTPS, использующий порт 443.

импортировать зависимости

Рекомендуется пройти напрямую через версию для поезда (на самом деле, автор исследовал, кодовое название версии для поезда на самом деле является названием станции лондонского метро, ​​как и нынешняяSpring CloudПоследняя версияGreenwich.SR1,GreenwichЭтот сайт можно найти на карте станций лондонского метро, ​​соответствующихSpringBootВерсия 2.1.x) ПредставленоSpring-Cloud-Gateway, так как это соответствует последней стабильной версииSpring-Cloudверсии, дополнительно из-заSpring-Cloud-Gatewayна основеNettyСреда выполнения запускается без необходимости импортаServletконтейнерspring-boot-starter-web.

Родительский POM импортирует следующую конфигурацию:

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.4.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

Подмодули или должны быть импортированыSpring-Cloud-GatewayМодуль POM представляет следующую конфигурацию:

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

Просто создайте класс запуска:

@SpringBootApplication
public class RouteServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(RouteServerApplication.class, args);
	}
}

Конфигурация шлюза

Конфигурация шлюза в конечном итоге должна быть преобразована вRouteDefinitionНабор конфигурации, интерфейс определения конфигурации выглядит следующим образом:

public interface RouteDefinitionLocator {
	Flux<RouteDefinition> getRouteDefinitions();
}

Конфигурация через файл YAML или стриминговая программная конфигурация (на самом деле в документации есть и ЭврикаDiscoveryClientКонфигурация, которая пока здесь не изучается), в конечном итоге заключается в созданииRouteDefinitionколлекция.

Конфигурация Yaml

Реализация конфигурацииPropertiesRouteDefinitionLocator, связанный с классом конфигурацииGatewayProperties:

spring:
  cloud:
    gateway:
      routes:
       - id: datetime_after_route    # <------ 这里是路由配置的ID
        uri: http://www.throwable.club  # <------ 这里是路由最终目标Server的URI(Host)
        predicates:                     # <------ 谓词集合配置,多个是用and逻辑连接
         - Path=/blog    # <------- Key(name)=Expression,键是谓词规则工厂的ID,值一般是匹配规则的正则表示

Конфигурация программной потоковой передачи

Конфигурация программного и потокового программирования требует зависимостейRouteLocatorBuilder, цель состоит в том, чтобы построитьRouteLocatorПример:

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
            .route(r -> r.path("/blog")
                .uri("http://www.throwable.club")
            )
            .build();
}

Фабрика предикатов маршрутизации

Spring Cloud Gatewayиспользовать маршрут какSpring-WebFluxизHandlerMappingчасть компонентной инфраструктуры, т.е.HandlerMappingПри сопоставлении настроенные правила маршрутизации также будут включены в механизм сопоставления.Spring Cloud GatewayОн содержит множество встроенных фабрик предикатов маршрутизации. Каждый из этих предикатов соответствует разным атрибутам HTTP-запроса. Можно использовать несколько фабрик предикатов маршрутов сandлогика объединена.

В настоящее времяSpring Cloud GatewayПредоставляемые встроенные фабрики предикатов маршрутов:

s-c-g-e-2.png

Укажите предикаты маршрутизации правил даты и времени

Существует три необязательных правила для предикатов маршрутизации, заданных сконфигурированным датой и временем:

  • Соответствие запросам до указанной даты и времени.
  • Соответствие запросам после указанной даты и времени.
  • Соответствие запросов между указанной датой и временем.

Стоит отметить, что настроенные дата и время должны соответствоватьZonedDateTimeФормат:

//年月日和时分秒用'T'分隔,接着-07:00是和UTC相差的时间,最后的[America/Denver]是所在的时间地区
2017-01-20T17:42:47.789-07:00[America/Denver]

Например, приложение шлюза2019-05-01T00:00:00+08:00[Asia/Shanghai]В режиме онлайн запросы после выхода в Интернет направляются в Австриюwww.throwable.club, то конфигурация следующая:

server 
  port: 9090
spring:
  cloud:
    gateway:
      routes:
       - id: datetime_after_route
        uri: http://www.throwable.club
        predicates:
         - After=2019-05-01T00:00:00+08:00[Asia/Shanghai]

На этом этапе просто запросите шлюзhttp://localhost:9090, запрос перенаправляетсяhttp://www.throwable.club.

Если вы хотите разрешить только2019-05-01T00:00:00+08:00[Asia/Shanghai]Предыдущий запрос, затем просто измените его на:

server 
  port: 9091
spring:
  cloud:
    gateway:
      routes:
       - id: datetime_before_route
        uri: http://www.throwable.club
        predicates:
         - Before=2019-05-01T00:00:00+08:00[Asia/Shanghai]

Если для запросов разрешено только время между двумя периодами даты и времени, просто измените его на:

server 
  port: 9090
spring:
  cloud:
    gateway:
      routes:
       - id: datetime_between_route
        uri: http://www.throwable.club
        predicates:
         - Between=2019-05-01T00:00:00+08:00[Asia/Shanghai],2019-05-02T00:00:00+08:00[Asia/Shanghai]

Тогда только запросы с 0:00 1 мая 2019 года до 0:00 2 мая могут маршрутизироваться нормально.

Предикат маршрутизации файлов cookie

CookieRoutePredicateFactoryВам необходимо указать два параметра: имя файла cookie и регулярное выражение (значение). Только когда имя и значение, соответствующие файлу cookie в запросе, совпадают со значением, настроенным в предикате маршрутизации файла cookie, соответствующее попадание может быть маршрутизировано.

server 
  port: 9090
spring:
  cloud:
    gateway:
      routes:
       - id: cookie_route
        uri: http://www.throwable.club
        predicates:
         - Cookie=doge,throwable

Запрос должен содержать файл cookie, имя — doge, а значение должно совпадать с регулярным выражением «throwable» для маршрутизации.http://www.throwable.club.

Вот попробуйте наладить заказ локальноOrderСервис, основанный на SpringBoot2.1.4, запускается на порту 9091:

// 入口类
@RestController
@RequestMapping(path = "/order")
@SpringBootApplication
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }

    @GetMapping(value = "/cookie")
    public ResponseEntity<String> cookie(@CookieValue(name = "doge") String doge) {
        return ResponseEntity.ok(doge);
    }
}

Заказать конфигурацию сервиса application.yaml:

spring:
  application:
    name: order-service
server:
  port: 9091

Конфигурация маршрутизации шлюза:

spring:
  application:
    name: route-server
  cloud:
    gateway:
      routes:
        - id: cookie_route
          uri: http://localhost:9091
          predicates:
            - Cookie=doge,throwable
curl http://localhost:9090/order/cookie --cookie "doge=throwable"

//响应结果
throwable

Предикат маршрутизации заголовка

HeaderRoutePredicateFactoryНеобходимо указать два параметра: имя заголовка и регулярное выражение (значение). Только когда имя и значение, соответствующие заголовку в запросе, совпадают со значением, настроенным в предикате маршрутизации заголовка, для маршрутизации может быть выполнено соответствующее попадание.

Добавить новую услугу заказа/headerКонечная точка:

@RestController
@RequestMapping(path = "/order")
@SpringBootApplication
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }

    @GetMapping(value = "/header")
    public ResponseEntity<String> header(@RequestHeader(name = "accessToken") String accessToken) {
        return ResponseEntity.ok(accessToken);
    }
}

Конфигурация маршрутизации шлюза выглядит следующим образом:

spring:
  cloud:
    gateway:
      routes:
        - id: header_route
          uri: http://localhost:9091
          predicates:
            - Header=accessToken,Doge
curl -H "accessToken:Doge" http://localhost:9090/order/header

//响应结果
Doge

Предикат маршрутизации хоста

HostRoutePredicateFactoryПросто укажите список имен хостов, каждый элемент в списке поддерживает стиль именования Ant, используйте.В качестве разделителя, используемого между несколькими элементами,выделить. Предикат маршрутизации хоста фактически предназначен для заголовка HTTP-запроса.HostАтрибуты.

Добавить новую услугу заказа/headerКонечная точка:

@RestController
@RequestMapping(path = "/order")
@SpringBootApplication
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }

    @GetMapping(value = "/host")
    public ResponseEntity<String> host(@RequestHeader(name = "Host") String host) {
        return ResponseEntity.ok(host);
    }
}

Конфигурация маршрутизации шлюза выглядит следующим образом:

spring:
  cloud:
    gateway:
      routes:
        - id: host_route
          uri: http://localhost:9091
          predicates:
            - Host=localhost:9090
curl http://localhost:9090/order/host

//响应结果
localhost:9091  # <--------- 这里要注意一下,路由到订单服务的时候,Host会被修改为localhost:9091

На самом деле можно настроить более разнообразные шаблоны сопоставления хостов, и даже могут поддерживаться переменные шаблона URI.

- Host=www.throwable.**,**.throwable.**

- Host={sub}.throwable.club

предикат маршрутизации метода запроса

MethodRoutePredicateFactoryТребуется только один параметр: метод HTTP-запроса для соответствия.

Конфигурация маршрутизации шлюза выглядит следующим образом:

spring:
  cloud:
    gateway:
      routes:
        - id: method_route
          uri: http://localhost:9091
          predicates:
            - Method=GET

При такой конфигурации все запросы к методу GET шлюза будут направляться наhttp://localhost:9091.

Добавить новую услугу заказа/getКонечная точка:

@GetMapping(value = "/get")
public ResponseEntity<String> get() {
    return ResponseEntity.ok("get");
}
curl http://localhost:9090/order/get

//响应结果
get 

предикат маршрутизации пути запроса

PathRoutePredicateFactoryнеобходимостьPathMatcherСписок путей шаблонов и необязательный аргумент flagsmatchOptionalTrailingSeparator. Это наиболее часто используемый предикат маршрутизации.

spring:
  cloud:
    gateway:
      routes:
        - id: path_route
          uri: http://localhost:9091
          predicates:
            - Path=/order/path
@GetMapping(value = "/path")
public ResponseEntity<String> path() {
    return ResponseEntity.ok("path");
}
curl http://localhost:9090/order/path

//响应结果
path 

Кроме того, через{segment}пути конфигурации заполнителя, такие как/foo/1или/foo/barили/bar/baz, если настроено в этой форме, при перенаправлении совпадающего попадания соответствующий контент в пути будет извлечен, а пара ключ-значение будет помещена вServerWebExchange.getAttributes()В коллекции КЛЮЧ естьServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE, эти извлеченные свойства можно использовать дляGatewayFilter Factoriesиспользовать.

предикат маршрутизации параметра запроса запроса

QueryRoutePredicateFactoryТребуется обязательный параметр запроса запроса (имя параметра) и необязательное регулярное выражение (регулярное выражение).

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://localhost:9091
        predicates:
        - Query=doge,throwabl.

Настроенный здесь параметрdoge, регулярное выражениеthrowabl..

@GetMapping(value = "/query")
public ResponseEntity<String> query(@RequestParam("name") String doge) {
  return ResponseEntity.ok(doge);
}
curl http://localhost:9090/order/query?doge=throwable

//响应结果
throwable 

Предикат маршрутизации удаленного IP-адреса

RemoteAddrRoutePredicateFactoryПравило сопоставления принимает список (минимум 1) строк в нотации CIDR (IPv4 или IPv6), например 192.168.0.1/16 (где 192.168.0.1 — удаленный IP-адрес, а 16 — маска подсети).

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: http://localhost:9091
        predicates:
        - RemoteAddr=127.0.0.1
@GetMapping(value = "/remote")
public ResponseEntity<String> remote() {
  return ResponseEntity.ok("remote");
}
curl http://localhost:9090/order/remote

//响应结果
remote 

Что касается предиката маршрутизации удаленной IP-маршрутизации, то на самом деле существует множество методов расширения, которые пока не будут здесь раскрываться.

Объединение нескольких предикатов маршрутизации

потому что конфигурация маршрутизацииpredicatesАтрибут на самом деле является списком, и несколько правил маршрутизации могут быть добавлены напрямую:

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: http://localhost:9091
        predicates:
        - RemoteAddr=xxxx
        - Path=/yyyy
        - Query=zzzz,aaaa

Эти правила используютсяandЛогически объединенный, например, приведенный выше пример эквивалентен:

request = ...
if(request.getRemoteAddr == 'xxxx' && request.getPath match '/yyyy' && request.getQuery('zzzz') match 'aaaa') {
    return true;
}
return false;

Фабрика шлюзовых фильтров

фильтр маршрутаGatewayFilterПозволяет изменять содержимое входящего HTTP-запроса или возвращаемого содержимого HTTP-ответа. Область действия фильтра маршрута — это конкретная конфигурация маршрута.Spring Cloud Gatewayпредоставляет множество встроенныхGatewayFilterФабрика, вы можете выбрать по мере необходимости.

так какGatewayFilterФабричных классов слишком много, приведу простой пример.

Если мы хотим прикрепить к некоторым запросам специальные заголовки HTTP-запроса, мы можем выбратьAddRequestHeaderX-Request-Foo:Bar,application.ymlследующее:

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-Foo,Bar

Тогда все HTTP-запросы от входа в шлюз будут добавлять специальный заголовок HTTP-запроса:X-Request-Foo:Bar.

В настоящее времяGatewayFilterВстроенная реализация фабрики выглядит следующим образом:

ID имя класса тип Функции
StripPrefix StripPrefixGatewayFilterFactory pre Удалите первую часть пути URL-адреса запроса, например, исходный путь запроса — /order/query, а после обработки — /query.
SetStatus SetStatusGatewayFilterFactory post Установите код состояния ответа на запрос, который будет проанализирован из org.springframework.http.HttpStatus
SetResponseHeader SetResponseHeaderGatewayFilterFactory post Установить (добавить) заголовок ответа на запрос ответа
SetRequestHeader SetRequestHeaderGatewayFilterFactory pre Установить (добавить) заголовки запроса
SetPath SetPathGatewayFilterFactory pre Установить (переопределить) путь запроса
SecureHeader SecureHeadersGatewayFilterFactory pre Установите заголовки запросов, связанные с безопасностью, см. SecureHeadersProperties
SaveSession SaveSessionGatewayFilterFactory pre Сохранить веб-сессию
RewriteResponseHeader RewriteResponseHeaderGatewayFilterFactory post заголовок повторного ответа
RewritePath RewritePathGatewayFilterFactory pre Переписать путь запроса
Retry RetryGatewayFilterFactory pre Повторить запросы в зависимости от условий
RequestSize RequestSizeGatewayFilterFactory pre Ограничьте размер запроса, единица измерения байт, если он превышает установленное значение, он будет возвращен413 Payload Too Large
RequestRateLimiter RequestRateLimiterGatewayFilterFactory pre Ограничение
RequestHeaderToRequestUri RequestHeaderToRequestUriGatewayFilterFactory pre Измените URL-адрес запроса на значение заголовка запроса
RemoveResponseHeader RemoveResponseHeaderGatewayFilterFactory post Удалить настроенные заголовки ответа
RemoveRequestHeader RemoveRequestHeaderGatewayFilterFactory pre Удалить настроенные заголовки запроса
RedirectTo RedirectToGatewayFilterFactory pre Перенаправление, необходимо указать код состояния HTTP и URL-адрес перенаправления
PreserveHostHeader PreserveHostHeaderGatewayFilterFactory pre Установите для атрибута saveHostHeader, переносимого запросом, значение true.
PrefixPath PrefixPathGatewayFilterFactory pre добавить предварительный путь к пути запроса
Hystrix HystrixGatewayFilterFactory pre Интеграция Hystrix
FallbackHeaders FallbackHeadersGatewayFilterFactory pre Hystrix выполняется, если логика перехода на более раннюю версию позволяет передавать сведения об исключении через заголовки запроса.
AddResponseHeader AddResponseHeaderGatewayFilterFactory post добавить заголовки ответа
AddRequestParameter AddRequestParameterGatewayFilterFactory pre Добавьте параметры запроса, ограничиваясь только параметром запроса URL-адреса.
AddRequestHeader AddRequestHeaderGatewayFilterFactory pre добавить заголовок запроса

GatewayFilterПри использовании фабрики необходимо знать ее идентификатор и метод настройки, который можно увидеть в публичном статическом внутреннем классе соответствующего класса фабрики.XXXXConfig.

Завод GlobalFilter

GlobalFilterФункция на самом деле такая же, какGatewayFilterто же самое, простоGlobalFilterОбласть действия — все конфигурации маршрутизации, не привязанные к указанной конфигурации маршрутизации. несколькоGlobalFilterв состоянии пройти@OrderилиgetOrder()способ указать каждыйGlobalFilterПорядок выполнения , чем меньше значение ордера, темGlobalFilterЧем выше приоритет выполнения.

Обратите внимание, что поскольку существует два типа фильтров, предварительный и пост-фильтр, если порядковое значение фильтра предварительного типа меньше, то оно должно быть на верхнем уровне цепочки предварительного фильтра, а если порядковое значение фильтра пост-типа меньше, то он должен быть в верхней части цепочки предварительных фильтров.Нижний слой цепочки предварительных фильтров. Схематическая диаграмма выглядит следующим образом:

s-c-g-e-3.png

Например, для достижения функции балансировки нагрузки,application.ymlКонфигурация выглядит следующим образом:

spring:
  cloud:
    gateway:
      routes:
      - id: myRoute
        uri: lb://myservice   # <-------- lb特殊标记会使用LoadBalancerClient搜索目标服务进行负载均衡
        predicates:
        - Path=/service/**

В настоящее времяSpring Cloud GatewayвстроенныйGlobalFilterследующее:

имя класса Функции
ForwardRoutingFilter перенаправить
LoadBalancerClientFilter балансировки нагрузки
NettyRoutingFilter Маршрутизация для HTTP-клиента Netty
NettyWriteResponseFilter Netty отвечает на операцию записи
RouteToRequestUrlFilter Обновить URL-адрес на основе конфигурации маршрута
WebsocketRoutingFilter Запросы Websocket перенаправляются вниз по течению

ВстроенныйGlobalFilterбольшинство иServerWebExchangeUtilsсвойства взаимосвязаны, поэтому я не буду здесь вдаваться в подробности.

Междоменная конфигурация

Шлюзы можно настроить для управления глобальным поведением CORS. Класс, соответствующий глобальной конфигурации CORS:CorsConfiguration, эта конфигурация представляет собой карту шаблонов URL. Напримерapplication.yamlФайлы следующие:

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "https://docs.spring.io"
            allowedMethods:
            - GET

В приведенном выше примере для всех запрошенных путей путь отdocs.spring.ioИ это запрос CORS с методом GET.

Корреляция конечной точки привода

вводитьspring-boot-starter-actuator, вам необходимо выполнить следующую настройку, чтобы включитьgatewayКонечные точки мониторинга:

management.endpoint.gateway.enabled=true 
management.endpoints.web.exposure.include=gateway

Список поддерживаемых в настоящее время конечных точек:

ID путь запроса HTTP-метод описывать
globalfilters /actuator/gateway/globalfilters GET Показать список GlobalFilters в конфигурации маршрутизации
routefilters /actuator/gateway/routefilters GET Отображает список GatewayFilters, привязанных к соответствующей конфигурации маршрутизации.
refresh /actuator/gateway/refresh POST Очистить кеш конфигурации маршрута
routes /actuator/gateway/routes GET Показать список определенных конфигураций маршрутизации
routes/{id} /actuator/gateway/routes/{id} GET Отображение конфигурации маршрутизации, определенной для соответствующего идентификатора.
routes/{id} /actuator/gateway/routes/{id} POST Добавить новую конфигурацию маршрута
routes/{id} /actuator/gateway/routes/{id} DELETE Удалить конфигурацию маршрутизации указанного идентификатора

в/actuator/gateway/routes/{id}Формат добавления нового параметра запроса конфигурации маршрута следующий:

{
  "id": "first_route",
  "predicates": [{
    "name": "Path",
    "args": {"doge":"/throwable"}
  }],
  "filters": [],
  "uri": "https://www.throwable.club",
  "order": 0
}

резюме

Хоть автор и низкоуровневый кодовый зверь, я давно сказал своим друзьям:

Реактивное программирование в сочетании с синхронным неблокирующим вводом-выводом или асинхронным неблокирующим вводом-выводом является основным направлением современных сред сетевого программирования. стать их соавторами.

Общие среды реактивного программирования:

  • ReactorиRxJava2ReactorПриложения JVM в бэкенде более распространены,RxJava2Это чаще встречается в клиентах APP, написанных для Android.
  • Reactor-Netty, который основан наReactorиNettyв упаковке.
  • Spring-WebFluxиSpring-Cloud-GatewaySpring-Cloud-GatewayполагатьсяSpring-WebFluxSpring-WebFluxНижний слой зависит отReactor-Netty.

В соответствии с этой цепной связью лучше всего систематически учитьсяReactorиNetty.

Использованная литература:

приложение

выберитеSpring-Cloud-GatewayНе только для использования новой технологии, но, что более важно, ее производительность была улучшена, сравнительные проектыspring-cloud-gateway-benchРезультат выглядит следующим образом:

Прокси-компонент (Прокси) Средняя задержка взаимодействия (Avg Latency) Среднее число запросов, обрабатываемых в секунду (Avg Requests/Sec)
Spring Cloud Gateway 6.61ms 32213.38
Linkered 7.62ms 28050.76
Zuul(1.x) 12.56ms 20800.13
Нет (прямой вызов) 2.09ms 116841.15

Оригинальная ссылка

(Конец этой статьи c-3-d e-a-20190504)

Технический публичный аккаунт ("Throwable Digest"), который время от времени выкладывает оригинальные технические статьи автора (никогда не занимайтесь плагиатом и не перепечатывайте):

Развлекательный паблик ("Скульптуры из песка каждый день") выбирает интересные картинки, тексты и видео скульптур из песка и время от времени выкладывает их, чтобы снять напряжение жизни и работы: