Spring Cloud Gateway过滤器配置,如何实现长尾词智能过滤?
- 内容介绍
- 文章标签
- 相关推荐
本文共计3847个文字,预计阅读时间需要16分钟。
Spring Cloud Gateway 过滤器配置,简单介绍如何集成Spring Cloud Gateway,下面我们来详细说说Spring Cloud Gateway的一些特性,它建立在Spring Boot之上。
Spring Cloud Gateway过滤器配置
我们只是简单的介绍了如何集成Spring Cloud Gateway ,下面我们来详细说说Spring Cloud Gateway 的一些特性
Spring Cloud Gateway 建立在 Spring Boot 2.x、Spring WebFlux 和 Project Reactor 之上。 因此,当您使用 Spring Cloud Gateway 时,您所知道的许多熟悉的同步库(例如 Spring Data 和 Spring Security)和模式可能并不适用。 如果您不熟悉这些项目,我们建议您在使用 Spring Cloud Gateway 之前先阅读他们的文档以熟悉一些新概念。
路由的配置方式
基于配制文件
Spring Cloud Gateway 有两种配置路由和过滤器的方法:快捷方式和完全扩展的参数。下面的大多数示例都使用快捷方式。
快捷方式配置
快捷方式配置由过滤器名称识别,后跟等号 ( =),后跟以逗号 ( ,) 分隔的参数值。
spring:
cloud:
gateway:
routes:
- id: after_route #路由的ID,保证全局唯一就行了,建议和服务名搭配命名
uri: example.org #uri,断言匹配时转发的uri
predicates:
- Cookie=mycookie,mycookievalue #断言,当断言匹配时就会转发至uri
复制代码
完全扩展的参数
完全扩展的参数看起来更像是带有名称/值对的标准 yaml 配置。通常,会有一把name钥匙和一把args钥匙。键是用于配置谓词或过滤器的args键值对映射。
spring:
cloud:
gateway:
routes:
- id: after_route #路由的ID,保证全局唯一就行了,建议和服务名搭配命名
uri: example.org #uri,断言匹配时转发的uri
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue
复制代码
之前我们项目中用到的路由匹配规则就是快捷方式
service-url:
user-service: localhost:8080
spring:
cloud:
gateway:
# 静态路由
routes:
- id: path_route
uri: ${service-url.user-service}/user/get/{id}
predicates:
- Path=/user/get/{id}
复制代码
这个配置的意思就是当请求的URI 与/user/get/{id} 相匹配时,就会将请求转发至localhost:8080/user/get/{id}
基于Java代码的配置方式
除了可以通过配制文件的方式,我们还可以通过Java代码进行硬编码,但是我个人不推荐这种方式,因为一是我认为在配制文件中配置路由可读性更高,另外就是配制文件可以整合配置中心实现动态路由,而显然,Java硬编码的方式是没法配合配置中心进行动态路由的,灵活性不高
// Spring 官方的例子
@SpringBootApplication
public class DemogatewayApplication {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/get")
.uri("localhost:9527/guonei时会自动转发到地址:news.baidu.com/guonei
* @author LiFang
* @date
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("path_route_atguigu",
r -> r.path("/guonei")
.uri("news.baidu.com/guonei")).build();
return routes.build();
}
@Bean
public RouteLocator customRouteLocator2(RouteLocatorBuilder builder) {
RouteLocatorBuilder.Builder routes = builder.routes();
routes.route("path_route_atguigu2",
r -> r.path("/guoji")
.uri("news.baidu.com/guoji")).build();
return routes.build();
}
}
复制代码
过滤器
Route Predicate 的使用
Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。 Spring Cloud Gateway包括许多内置的Route Predicate工厂。 所有这些Predicate都与HTTP请求的不同属性匹配。 多个Route Predicate工厂可以进行组合,下面我们来介绍下一些常用的Route Predicate。
注意:Predicate中提到的配置都在application-predicate.yml文件中进行修改,并用该配置启动api-gateway服务。
Spring Cloud Gateway自带了很多断言过滤器,可以让我们在断言中使用,我这里只简单的列举几个常用的,想要详细了解的可以查阅官方文档
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
复制代码
带有cookie为username=macro的请求可以匹配该路由
Header Route Predicate
带有指定请求头的请求会匹配该路由
spring:
cloud:
gateway:
routes:
- id: header_route
uri: ${service-url.user-service}
predicates:
- Header=X-Request-Id, \d+
复制代码
带有请求头为X-Request-Id:123的请求可以匹配该路由
Method Route Predicate
发送指定方法的请求会匹配该路由
spring:
cloud:
gateway:
routes:
- id: method_route
uri: ${service-url.user-service}
predicates:
- Method=GET
复制代码
GET请求可以匹配该路由
Path Route Predicate
发送指定路径的请求会匹配该路由
spring:
cloud:
gateway:
routes:
- id: path_route
uri: ${service-url.user-service}/user/{id}
predicates:
- Path=/user/{id}
复制代码
Query Route Predicate
带指定查询参数的请求可以匹配该路由
spring:
cloud:
gateway:
routes:
- id: query_route
uri: ${service-url.user-service}/user/getByUsername
predicates:
- Query=username
复制代码
带username=macro查询参数的请求可以匹配该路由。
RemoteAddr Route Predicate
从指定远程地址发起的请求可以匹配该路由
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: ${service-url.user-service}
predicates:
- RemoteAddr=192.168.1.1/24
复制代码
从192.168.1.1发起请求可以匹配该路由
Weight Route Predicate
使用权重来路由相应请求,以下表示有80%的请求会被路由到localhost:8201,20%会被路由到localhost:8202
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: localhost:8201
predicates:
- Weight=group1, 8
- id: weight_low
uri: localhost:8202
predicates:
- Weight=group1, 2
复制代码
Route Filter 的使用
路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。Spring Cloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生,下面我们介绍下常用路由过滤器的用法。
AddRequestHeader
AddRequestHeader GatewayFilter 采用名称和值参数。 以下示例配置一个 AddRequestHeader GatewayFilter:
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: example.org
filters:
- AddRequestHeader=X-Request-red, blue
复制代码
这个例子将 X-Request-red:blue 标头添加到所有匹配请求的下游请求标头中
AddRequestParameter GatewayFilter
给请求添加参数的过滤器
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: localhost:8201
filters:
- AddRequestParameter=username, macro
predicates:
- Method=GET
复制代码
以上配置会对GET请求添加username=macro的请求参数,相当于发起该请求:
curl localhost:8201/user/getByUsername?username=macro
复制代码
StripPrefix GatewayFilter
对指定数量的路径前缀进行去除的过滤器
spring:
cloud:
gateway:
routes:
- id: strip_prefix_route
uri: localhost:8201
predicates:
- Path=/user-service/**
filters:
- StripPrefix=2
复制代码
以上配置会把以/user-service/开头的请求的路径去除两位,通过curl工具使用以下命令进行测试
curl localhost:9201/user-service/a/user/1
复制代码
相当于发起该请求:
curl localhost:8201/user/1
复制代码
PrefixPath GatewayFilter
与StripPrefix过滤器恰好相反,会对原有路径进行增加操作的过滤器。
spring:
cloud:
gateway:
routes:
- id: prefix_path_route
uri: localhost:8201
predicates:
- Method=GET
filters:
- PrefixPath=/user
复制代码
以上配置会对所有GET请求添加/user路径前缀,通过curl工具使用以下命令进行测试。
curl localhost:9201/1
复制代码
相当于发起该请求:
curl localhost:8201/user/1
复制代码
Hystrix GatewayFilter
Hystrix 过滤器允许你将断路器功能添加到网关路由中,使你的服务免受级联故障的影响,并提供服务降级处理。
- 要开启断路器功能,我们需要在pom.xml中添加Hystrix的相关依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
复制代码
- 然后添加相关服务降级的处理类:
@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: localhost:8201
predicates:
- Method=GET
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/fallback
复制代码
- 关闭user-service,调用该地址进行测试:localhost:9201/user/1 ,发现已经返回了服务降级的处理信息。
RequestRateLimiter GatewayFilter
RequestRateLimiter 过滤器可以用于限流,使用RateLimiter实现来确定是否允许当前请求继续进行,如果请求太大默认会返回HTTP 429-太多请求状态。
- 在pom.xml中添加相关依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
复制代码
- 添加限流策略的配置类,这里有两种策略一种是根据请求参数中的username进行限流,另一种是根据访问IP进行限流
@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: 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
复制代码
Retry GatewayFilter
对路由请求进行重试的过滤器,可以根据路由请求返回的HTTP状态码来确定是否进行重试。
- 修改配置文件:
spring:
cloud:
gateway:
routes:
- id: retry_route
uri: 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时会进行重试,访问测试地址:localhost:9201/user/111
- 可以发现user-service控制台报错2次,说明进行了一次重试。
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]
复制代码
添加默认过滤器
要添加过滤器并将其应用于所有路由,您可以使用spring.cloud.gateway.default-filters. 此属性采用过滤器列表。以下清单定义了一组默认过滤器:
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/docs.spring.io"
allowedMethods:
- GET
复制代码
在前面的示例中,允许来自docs.spring.io所有 GET 请求路径的请求的 CORS 请求。
要为某些网关路由谓词未处理的请求提供相同的 CORS 配置,请将spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping属性设置为true.
通常的配置是:
spring:
cloud:
gateway:
default-filters:
# gateway 和下游系统同时支持了跨域,都会向 response header 中增加 Access-Control-Allow-Origin*,所以出现重复的 *。所以需要使用DedupeResponseHeader 来处理一下响应头重复的问题
- DedupeResponseHeader=Access-Control-Allow-Origin, RETAIN_UNIQUE
globalcors:
cors-configurations:
'[/**]':
# 允许携带认证信息
allow-credentials: true
# 允许跨域的源(网站域名/ip),设置*为全部
allowedOrigins: "*"
# 允许跨域的method, 默认为GET和OPTIONS,设置*为全部
allowedMethods: "*"
# 允许跨域请求里的head字段,设置*为全部
allowedHeaders: "*"
复制代码
至此,关于Spring Cloud Gateway的进一步解释到这里就结束啦,后面我们会继续介绍Spring Cloud Gateway的动态路由配置以及负载均衡
本文共计3847个文字,预计阅读时间需要16分钟。
Spring Cloud Gateway 过滤器配置,简单介绍如何集成Spring Cloud Gateway,下面我们来详细说说Spring Cloud Gateway的一些特性,它建立在Spring Boot之上。
Spring Cloud Gateway过滤器配置
我们只是简单的介绍了如何集成Spring Cloud Gateway ,下面我们来详细说说Spring Cloud Gateway 的一些特性
Spring Cloud Gateway 建立在 Spring Boot 2.x、Spring WebFlux 和 Project Reactor 之上。 因此,当您使用 Spring Cloud Gateway 时,您所知道的许多熟悉的同步库(例如 Spring Data 和 Spring Security)和模式可能并不适用。 如果您不熟悉这些项目,我们建议您在使用 Spring Cloud Gateway 之前先阅读他们的文档以熟悉一些新概念。
路由的配置方式
基于配制文件
Spring Cloud Gateway 有两种配置路由和过滤器的方法:快捷方式和完全扩展的参数。下面的大多数示例都使用快捷方式。
快捷方式配置
快捷方式配置由过滤器名称识别,后跟等号 ( =),后跟以逗号 ( ,) 分隔的参数值。
spring:
cloud:
gateway:
routes:
- id: after_route #路由的ID,保证全局唯一就行了,建议和服务名搭配命名
uri: example.org #uri,断言匹配时转发的uri
predicates:
- Cookie=mycookie,mycookievalue #断言,当断言匹配时就会转发至uri
复制代码
完全扩展的参数
完全扩展的参数看起来更像是带有名称/值对的标准 yaml 配置。通常,会有一把name钥匙和一把args钥匙。键是用于配置谓词或过滤器的args键值对映射。
spring:
cloud:
gateway:
routes:
- id: after_route #路由的ID,保证全局唯一就行了,建议和服务名搭配命名
uri: example.org #uri,断言匹配时转发的uri
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue
复制代码
之前我们项目中用到的路由匹配规则就是快捷方式
service-url:
user-service: localhost:8080
spring:
cloud:
gateway:
# 静态路由
routes:
- id: path_route
uri: ${service-url.user-service}/user/get/{id}
predicates:
- Path=/user/get/{id}
复制代码
这个配置的意思就是当请求的URI 与/user/get/{id} 相匹配时,就会将请求转发至localhost:8080/user/get/{id}
基于Java代码的配置方式
除了可以通过配制文件的方式,我们还可以通过Java代码进行硬编码,但是我个人不推荐这种方式,因为一是我认为在配制文件中配置路由可读性更高,另外就是配制文件可以整合配置中心实现动态路由,而显然,Java硬编码的方式是没法配合配置中心进行动态路由的,灵活性不高
// Spring 官方的例子
@SpringBootApplication
public class DemogatewayApplication {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/get")
.uri("localhost:9527/guonei时会自动转发到地址:news.baidu.com/guonei
* @author LiFang
* @date
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("path_route_atguigu",
r -> r.path("/guonei")
.uri("news.baidu.com/guonei")).build();
return routes.build();
}
@Bean
public RouteLocator customRouteLocator2(RouteLocatorBuilder builder) {
RouteLocatorBuilder.Builder routes = builder.routes();
routes.route("path_route_atguigu2",
r -> r.path("/guoji")
.uri("news.baidu.com/guoji")).build();
return routes.build();
}
}
复制代码
过滤器
Route Predicate 的使用
Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。 Spring Cloud Gateway包括许多内置的Route Predicate工厂。 所有这些Predicate都与HTTP请求的不同属性匹配。 多个Route Predicate工厂可以进行组合,下面我们来介绍下一些常用的Route Predicate。
注意:Predicate中提到的配置都在application-predicate.yml文件中进行修改,并用该配置启动api-gateway服务。
Spring Cloud Gateway自带了很多断言过滤器,可以让我们在断言中使用,我这里只简单的列举几个常用的,想要详细了解的可以查阅官方文档
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
复制代码
带有cookie为username=macro的请求可以匹配该路由
Header Route Predicate
带有指定请求头的请求会匹配该路由
spring:
cloud:
gateway:
routes:
- id: header_route
uri: ${service-url.user-service}
predicates:
- Header=X-Request-Id, \d+
复制代码
带有请求头为X-Request-Id:123的请求可以匹配该路由
Method Route Predicate
发送指定方法的请求会匹配该路由
spring:
cloud:
gateway:
routes:
- id: method_route
uri: ${service-url.user-service}
predicates:
- Method=GET
复制代码
GET请求可以匹配该路由
Path Route Predicate
发送指定路径的请求会匹配该路由
spring:
cloud:
gateway:
routes:
- id: path_route
uri: ${service-url.user-service}/user/{id}
predicates:
- Path=/user/{id}
复制代码
Query Route Predicate
带指定查询参数的请求可以匹配该路由
spring:
cloud:
gateway:
routes:
- id: query_route
uri: ${service-url.user-service}/user/getByUsername
predicates:
- Query=username
复制代码
带username=macro查询参数的请求可以匹配该路由。
RemoteAddr Route Predicate
从指定远程地址发起的请求可以匹配该路由
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: ${service-url.user-service}
predicates:
- RemoteAddr=192.168.1.1/24
复制代码
从192.168.1.1发起请求可以匹配该路由
Weight Route Predicate
使用权重来路由相应请求,以下表示有80%的请求会被路由到localhost:8201,20%会被路由到localhost:8202
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: localhost:8201
predicates:
- Weight=group1, 8
- id: weight_low
uri: localhost:8202
predicates:
- Weight=group1, 2
复制代码
Route Filter 的使用
路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。Spring Cloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生,下面我们介绍下常用路由过滤器的用法。
AddRequestHeader
AddRequestHeader GatewayFilter 采用名称和值参数。 以下示例配置一个 AddRequestHeader GatewayFilter:
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: example.org
filters:
- AddRequestHeader=X-Request-red, blue
复制代码
这个例子将 X-Request-red:blue 标头添加到所有匹配请求的下游请求标头中
AddRequestParameter GatewayFilter
给请求添加参数的过滤器
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: localhost:8201
filters:
- AddRequestParameter=username, macro
predicates:
- Method=GET
复制代码
以上配置会对GET请求添加username=macro的请求参数,相当于发起该请求:
curl localhost:8201/user/getByUsername?username=macro
复制代码
StripPrefix GatewayFilter
对指定数量的路径前缀进行去除的过滤器
spring:
cloud:
gateway:
routes:
- id: strip_prefix_route
uri: localhost:8201
predicates:
- Path=/user-service/**
filters:
- StripPrefix=2
复制代码
以上配置会把以/user-service/开头的请求的路径去除两位,通过curl工具使用以下命令进行测试
curl localhost:9201/user-service/a/user/1
复制代码
相当于发起该请求:
curl localhost:8201/user/1
复制代码
PrefixPath GatewayFilter
与StripPrefix过滤器恰好相反,会对原有路径进行增加操作的过滤器。
spring:
cloud:
gateway:
routes:
- id: prefix_path_route
uri: localhost:8201
predicates:
- Method=GET
filters:
- PrefixPath=/user
复制代码
以上配置会对所有GET请求添加/user路径前缀,通过curl工具使用以下命令进行测试。
curl localhost:9201/1
复制代码
相当于发起该请求:
curl localhost:8201/user/1
复制代码
Hystrix GatewayFilter
Hystrix 过滤器允许你将断路器功能添加到网关路由中,使你的服务免受级联故障的影响,并提供服务降级处理。
- 要开启断路器功能,我们需要在pom.xml中添加Hystrix的相关依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
复制代码
- 然后添加相关服务降级的处理类:
@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: localhost:8201
predicates:
- Method=GET
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/fallback
复制代码
- 关闭user-service,调用该地址进行测试:localhost:9201/user/1 ,发现已经返回了服务降级的处理信息。
RequestRateLimiter GatewayFilter
RequestRateLimiter 过滤器可以用于限流,使用RateLimiter实现来确定是否允许当前请求继续进行,如果请求太大默认会返回HTTP 429-太多请求状态。
- 在pom.xml中添加相关依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
复制代码
- 添加限流策略的配置类,这里有两种策略一种是根据请求参数中的username进行限流,另一种是根据访问IP进行限流
@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: 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
复制代码
Retry GatewayFilter
对路由请求进行重试的过滤器,可以根据路由请求返回的HTTP状态码来确定是否进行重试。
- 修改配置文件:
spring:
cloud:
gateway:
routes:
- id: retry_route
uri: 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时会进行重试,访问测试地址:localhost:9201/user/111
- 可以发现user-service控制台报错2次,说明进行了一次重试。
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]
复制代码
添加默认过滤器
要添加过滤器并将其应用于所有路由,您可以使用spring.cloud.gateway.default-filters. 此属性采用过滤器列表。以下清单定义了一组默认过滤器:
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/docs.spring.io"
allowedMethods:
- GET
复制代码
在前面的示例中,允许来自docs.spring.io所有 GET 请求路径的请求的 CORS 请求。
要为某些网关路由谓词未处理的请求提供相同的 CORS 配置,请将spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping属性设置为true.
通常的配置是:
spring:
cloud:
gateway:
default-filters:
# gateway 和下游系统同时支持了跨域,都会向 response header 中增加 Access-Control-Allow-Origin*,所以出现重复的 *。所以需要使用DedupeResponseHeader 来处理一下响应头重复的问题
- DedupeResponseHeader=Access-Control-Allow-Origin, RETAIN_UNIQUE
globalcors:
cors-configurations:
'[/**]':
# 允许携带认证信息
allow-credentials: true
# 允许跨域的源(网站域名/ip),设置*为全部
allowedOrigins: "*"
# 允许跨域的method, 默认为GET和OPTIONS,设置*为全部
allowedMethods: "*"
# 允许跨域请求里的head字段,设置*为全部
allowedHeaders: "*"
复制代码
至此,关于Spring Cloud Gateway的进一步解释到这里就结束啦,后面我们会继续介绍Spring Cloud Gateway的动态路由配置以及负载均衡

