Адрес фактического проекта электронной коммерции SpringBoot (20k+star):GitHub.com/macro-positive/…
Резюме
Spring Cloud Gateway обеспечивает поддержку шлюза API для приложений SpringBoot с мощными интеллектуальными функциями маршрутизации и фильтрации.В этой статье будет подробно рассказано о его использовании.
Введение в шлюз
Gateway — это служба шлюза API, созданная на основе экосистемы Spring и основанная на таких технологиях, как Spring 5, Spring Boot 2 и Project Reactor. Шлюз призван предоставить простой и эффективный способ маршрутизации API, а также предоставить некоторые мощные функции фильтрации, такие как: автоматический выключатель, ограничение тока, повторная попытка и т. д.
Spring Cloud Gateway имеет следующие функции:
- Построен на Spring Framework 5, Project Reactor и Spring Boot 2.0;
- Динамическая маршрутизация: возможность сопоставления любого атрибута запроса;
- Для маршрутов можно указать Predicate и Filter;
- Интегрируйте функцию автоматического выключателя Hystrix;
- Интеграция функции обнаружения службы Spring Cloud;
- Простой в написании предикат и фильтр;
- Функция ограничения тока запроса;
- Перезапись пути поддерживается.
Связанные концепции
- Маршрут (Маршрут): Маршрут является основным модулем для построения шлюза.Он состоит из идентификатора, целевого URI, ряда утверждений и фильтров.Если утверждение истинно, маршрут соответствует;
- Предикат: относится к предикату функции Java 8. Тип ввода — ServerWebExchange в среде Spring. Это позволяет разработчикам сопоставлять все в HTTP-запросе, например заголовки или параметры запроса. Маршрутизировать, если запрос соответствует утверждению;
- Фильтр (filter): относится к экземпляру GatewayFilter в среде Spring.Используя фильтр, запрос можно изменить до и после маршрутизации запроса.
Создайте модуль API-шлюза
Здесь мы создаем модуль API-шлюза, чтобы продемонстрировать общие функции шлюза.
Добавьте связанные зависимости в pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Два разных способа настройки маршрутизации
Шлюз предоставляет два разных способа настройки маршрутизации: один — через файл yml, другой — через Java Bean, мы представим их отдельно ниже.
Использовать yml-конфигурацию
- Настройте в application.yml:
server:
port: 9201
service-url:
user-service: http://localhost:8201
spring:
cloud:
gateway:
routes:
- id: path_route #路由的ID
uri: ${service-url.user-service}/user/{id} #匹配后路由地址
predicates: # 断言,路径相匹配的进行路由
- Path=/user/{id}
-
Запустите службы eureka-server, user-service и api-gateway и вызовите адресный тест:http://localhost:9201/user/1
-
Мы обнаружили, что запрос был перенаправлен на путь user-service:http://localhost:8201/user/1
Конфигурация с использованием Java Beans
- Добавьте связанные классы конфигурации и настройте объект RouteLocator:
/**
* Created by macro on 2019/9/24.
*/
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route2", r -> r.path("/user/getByUsername")
.uri("http://localhost:8201/user/getByUsername"))
.build();
}
}
-
Перезапустите службу api-gateway и вызовите проверку адреса:http://localhost:9201/user/getByUsername?username=macro
-
Мы обнаружили, что запрос был перенаправлен на путь user-service:http://localhost:8201/user/getByUsername?username=macro
Использование предиката маршрута
Spring Cloud Gateway реализует сопоставление маршрутов как часть инфраструктуры Spring WebFlux HandlerMapping. Spring Cloud Gateway включает ряд встроенных фабрик предикатов маршрутов. Все эти предикаты соответствуют различным атрибутам HTTP-запроса. Несколько фабрик предикатов маршрутов могут быть объединены Давайте представим некоторые часто используемые предикаты маршрутов.
Примечание. Конфигурация, указанная в Predicate, изменяется в файле application-predicate.yml, и служба API-шлюза запускается с этой конфигурацией.
After Route Predicate
Запросы после указанного времени будут соответствовать этому маршруту.
spring:
cloud:
gateway:
routes:
- id: after_route
uri: ${service-url.user-service}
predicates:
- After=2019-09-24T16:30:00+08:00[Asia/Shanghai]
Before Route Predicate
Запросы до указанного времени будут соответствовать этому маршруту.
spring:
cloud:
gateway:
routes:
- id: before_route
uri: ${service-url.user-service}
predicates:
- Before=2019-09-24T16:30:00+08:00[Asia/Shanghai]
Between Route Predicate
Запросы в течение указанного интервала времени будут соответствовать этому маршруту.
spring:
cloud:
gateway:
routes:
- id: before_route
uri: ${service-url.user-service}
predicates:
- Between=2019-09-24T16:30:00+08:00[Asia/Shanghai], 2019-09-25T16:30:00+08:00[Asia/Shanghai]
Cookie Route Predicate
Запросы с указанным файлом cookie будут соответствовать этому маршруту.
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: ${service-url.user-service}
predicates:
- Cookie=username,macro
Используйте инструмент curl, чтобы отправить файл cookie какusername=macro
запросы могут соответствовать этому маршруту.
curl http://localhost:9201/user/1 --cookie "username=macro"
Header Route Predicate
Запросы с указанными заголовками будут соответствовать этому маршруту.
spring:
cloud:
gateway:
routes:
- id: header_route
uri: ${service-url.user-service}
predicates:
- Header=X-Request-Id, \d+
Используйте инструмент curl для отправки заголовков запроса в видеX-Request-Id:123
запросы могут соответствовать этому маршруту.
curl http://localhost:9201/user/1 -H "X-Request-Id:123"
Host Route Predicate
Запросы с указанным Хостом будут соответствовать этому маршруту.
spring:
cloud:
gateway:
routes:
- id: host_route
uri: ${service-url.user-service}
predicates:
- Host=**.macrozheng.com
Используйте инструмент curl для отправки заголовков запроса в видеHost:www.macrozheng.com
запросы могут соответствовать этому маршруту.
curl http://localhost:9201/user/1 -H "Host:www.macrozheng.com"
Method Route Predicate
Отправка запроса на указанный метод будет соответствовать этому маршруту.
spring:
cloud:
gateway:
routes:
- id: method_route
uri: ${service-url.user-service}
predicates:
- Method=GET
Этот маршрут можно сопоставить, отправив запрос GET с помощью инструмента curl.
curl http://localhost:9201/user/1
Отправка запроса POST с помощью инструмента curl не может соответствовать этому маршруту.
curl -X POST http://localhost:9201/user/1
Path Route Predicate
Отправка запроса по указанному пути будет соответствовать этому маршруту.
spring:
cloud:
gateway:
routes:
- id: path_route
uri: ${service-url.user-service}/user/{id}
predicates:
- Path=/user/{id}
Отправить с помощью инструмента завиток/user/1
Запросы пути могут соответствовать этому маршруту.
curl http://localhost:9201/user/1
Отправить с помощью инструмента завиток/abc/1
Запрос маршрута не может соответствовать маршруту.
curl http://localhost:9201/abc/1
Query Route Predicate
Запросы с указанными параметрами запроса могут соответствовать этому маршруту.
spring:
cloud:
gateway:
routes:
- id: query_route
uri: ${service-url.user-service}/user/getByUsername
predicates:
- Query=username
Отправьте ленту с помощью инструмента скручиванияusername=macro
Запросы с параметрами запроса могут соответствовать этому маршруту.
curl http://localhost:9201/user/getByUsername?username=macro
Отправка запроса с параметрами запроса или без них с помощью инструмента curl не может соответствовать этому маршруту.
curl http://localhost:9201/user/getByUsername
RemoteAddr Route Predicate
Запросы, исходящие с указанного удаленного адреса, могут соответствовать этому маршруту.
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: ${service-url.user-service}
predicates:
- RemoteAddr=192.168.1.1/24
Использование инструмента curl для инициирования запроса от 192.168.1.1 может соответствовать этому маршруту.
curl http://localhost:9201/user/1
Weight Route Predicate
Используйте вес для маршрутизации соответствующего запроса, следующее означает, что 80 % запросов будут перенаправлены на локальный хост: 8201, а 20 % — на локальный хост: 8202.
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: http://localhost:8201
predicates:
- Weight=group1, 8
- id: weight_low
uri: http://localhost:8202
predicates:
- Weight=group1, 2
Использование фильтра маршрута
Фильтры маршрутов можно использовать для изменения входящих HTTP-запросов и возвращаемых HTTP-ответов.Фильтры маршрутов можно использовать только путем указания маршрутов. Spring Cloud Gateway имеет множество встроенных фильтров маршрутизации, все из которых генерируются фабричным классом GatewayFilter. Давайте представим использование общих фильтров маршрутизации.
AddRequestParameter GatewayFilter
Фильтр, добавляющий параметры к запросу.
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: http://localhost:8201
filters:
- AddRequestParameter=username, macro
predicates:
- Method=GET
Приведенная выше конфигурация добавит к запросу GETusername=macro
Параметры запроса проверяются инструментом curl с помощью следующей команды.
curl http://localhost:9201/user/getByUsername
Эквивалентно инициированию запроса:
curl http://localhost:8201/user/getByUsername?username=macro
StripPrefix GatewayFilter
Фильтр, который удаляет указанное количество префиксов пути.
spring:
cloud:
gateway:
routes:
- id: strip_prefix_route
uri: http://localhost:8201
predicates:
- Path=/user-service/**
filters:
- StripPrefix=2
Вышеупомянутая конфигурация начнется с/user-service/
Удалите две цифры из пути запроса в начале и используйте следующую команду, чтобы проверить его с помощью инструмента curl.
curl http://localhost:9201/user-service/a/user/1
Эквивалентно инициированию запроса:
curl http://localhost:8201/user/1
PrefixPath GatewayFilter
В отличие от фильтра StripPrefix, фильтр, добавляющий операции к исходному пути.
spring:
cloud:
gateway:
routes:
- id: prefix_path_route
uri: http://localhost:8201
predicates:
- Method=GET
filters:
- PrefixPath=/user
Приведенная выше конфигурация добавит ко всем запросам GET/user
Префикс пути, проверенный с помощью следующей команды с помощью инструмента curl.
curl http://localhost:9201/1
Эквивалентно инициированию запроса:
curl http://localhost:8201/user/1
Hystrix GatewayFilter
Фильтры Hystrix позволяют добавлять функции прерывателя цепи к маршрутам шлюза, изолировать ваши службы от каскадных сбоев и обеспечивать обработку деградации службы.
- Чтобы включить функцию прерывателя цепи, нам нужно добавить соответствующие зависимости Hystrix в pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- Затем добавьте соответствующий класс обработки перехода на более раннюю версию службы:
/**
* Created by macro on 2019/9/25.
*/
@RestController
public class FallbackController {
@GetMapping("/fallback")
public Object fallback() {
Map<String,Object> result = new HashMap<>();
result.put("data",null);
result.put("message","Get request fallback!");
result.put("code",500);
return result;
}
}
- Добавьте соответствующую конфигурацию в application-filter.yml, и при возникновении ошибки маршрутизации она будет перенаправлена на контроллер для обработки понижения службы:
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: http://localhost:8201
predicates:
- Method=GET
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/fallback
- Закройте пользовательский сервис и вызовите этот адрес для тестирования:http://localhost:9201/user/1обнаружено, что была возвращена информация об обработке ухудшения обслуживания.
RequestRateLimiter GatewayFilter
Для ограничения потока можно использовать фильтр RequestRateLimiter. Используйте реализацию RateLimiter, чтобы определить, следует ли разрешить продолжение текущего запроса. Если запрос слишком велик, он по умолчанию возвращает статус HTTP 429-Too Many Requests.
- Добавьте связанные зависимости в pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
- Добавьте класс конфигурации текущей политики ограничения.Здесь есть две стратегии: одна — ограничить ток в соответствии с именем пользователя в параметре запроса, а другая — ограничить ток в соответствии с IP-адресом доступа;
/**
* Created by macro on 2019/9/25.
*/
@Configuration
public class RedisRateLimiterConfig {
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("username"));
}
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
}
- Мы используем Redis для ограничения тока, поэтому нам нужно добавить конфигурацию Redis и RequestRateLimiter, здесь все GET-запросы ограничены IP;
server:
port: 9201
spring:
redis:
host: localhost
password: 123456
port: 6379
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: http://localhost:8201
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 #每秒允许处理的请求数量
redis-rate-limiter.burstCapacity: 2 #每秒最大处理的请求数量
key-resolver: "#{@ipKeyResolver}" #限流策略,对应策略的Bean
predicates:
- Method=GET
logging:
level:
org.springframework.cloud.gateway: debug
- Запросить адрес несколько раз:http://localhost:9201/user/1, будет возвращена ошибка с кодом состояния 429;
Retry GatewayFilter
Фильтр для повторной попытки запроса маршрутизации может определить, следует ли повторить попытку, в соответствии с кодом состояния HTTP, возвращенным запросом маршрутизации.
- Измените файл конфигурации:
spring:
cloud:
gateway:
routes:
- id: retry_route
uri: http://localhost:8201
predicates:
- Method=GET
filters:
- name: Retry
args:
retries: 1 #需要进行重试的次数
statuses: BAD_GATEWAY #返回哪个状态码需要进行重试,返回状态码为5XX进行重试
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
-
Когда вызов вернет 500, он повторит попытку, посетите тестовый адрес:http://localhost:9201/user/111
-
Можно обнаружить, что консоль службы пользователя сообщает о двух ошибках, указывающих на повторную попытку.
2019-10-27 14:08:53.435 ERROR 2280 --- [nio-8201-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
at com.macro.cloud.controller.UserController.getUser(UserController.java:34) ~[classes/:na]
Использовать вместе с реестром
мы говорили в прошлый разИспользование Zuul в качестве шлюзаПри использовании вместе с реестром Zuul по умолчанию создает динамический маршрут с именем службы path на основе списка служб, зарегистрированного в реестре.Шлюз также реализует эту функцию. Ниже мы покажем, как Gateway использует динамические маршруты и фильтры по умолчанию в сочетании с реестром.
Используйте динамическую маршрутизацию
- Добавьте связанные зависимости в pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- Добавьте файл конфигурации application-eureka.yml:
server:
port: 9201
spring:
application:
name: api-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能
lower-case-service-id: true #使用小写服务名,默认是大写
eureka:
client:
service-url:
defaultZone: http://localhost:8001/eureka/
logging:
level:
org.springframework.cloud.gateway: debug
- Используйте файл конфигурации application-eureka.yml для запуска службы API-шлюза, доступа к http://localhost:9201/user-service/user/1 и маршрутизации к http://localhost:8201/user/1 пользователя. -сервис .
использовать фильтр
При использовании фильтров совместно с реестром нужно обратить внимание на то, что протокол uri
lb
, чтобы можно было включить функцию балансировки нагрузки шлюза.
- Измените файл application-eureka.yml и используйте фильтр PrefixPath, который будет добавлен ко всем путям GET-запросов.
/user
путь и маршрут;
server:
port: 9201
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: prefixpath_route
uri: lb://user-service #此处需要使用lb协议
predicates:
- Method=GET
filters:
- PrefixPath=/user
discovery:
locator:
enabled: true
eureka:
client:
service-url:
defaultZone: http://localhost:8001/eureka/
logging:
level:
org.springframework.cloud.gateway: debug
- Используйте файл конфигурации application-eureka.yml для запуска службы API-шлюза, доступа к http://localhost:9201/1 и маршрутизации к http://localhost:8201/user/1 пользовательской службы.
используемые модули
springcloud-learning
├── eureka-server -- eureka注册中心
├── user-service -- 提供User对象CRUD接口的服务
└── api-gateway -- gateway作为网关的测试服务
Адрес исходного кода проекта
публика
проект торгового центраПолный набор учебных пособий сериализуется,Обратите внимание на публичный аккаунтПолучите это прямо сейчас.