文章目录
- Spring Cloud Gateway 概述及工作原理
- Spring Cloud Gateway 工程
- 断言(Predicate)
- GatewayFilter(过滤器)
- 1. AddRequestHeader(请求头添加参数)
- 2. AddRequestParameter(Query)
- 3. AddResponseHeader(响应头添加参数)
- 4. DedupeResponseHeader(响应头重复数据消除)
- 5. Hystrix(熔断)
- 6. RequestRateLimiter(请求限速)
- 7. RedirectTo(重定向)
- 8. RewritePath(重写路径)
- 9. CircuitBreaker(断路器)
- 10. FallbackHeaders(回调头添加信息)
- 11. MapRequestHeader(请求头映射)
- 12. PrefixPath(路径前缀)
- 13. PreserveHostHeader(保留主机标头)
- 14. SetHostHeader(设置主机头)
- 15. RemoveRequestHeader(删除RequestHeader信息)
- 16. RemoveRequestParameter(删除请求参数)
- 17. RemoveResponseHeader(删除ResponseHeader参数)
- 18. Retry(请求重试)
- 18. SecureHeaders(安全Headers信息)
- 19. SetPath(设置Path)
- 20. SetRequestHeader(设置RequestHeaders信息)
- 21. SetResponseHeader(设置ResponseHeader信息)
- 22. RewriteResponseHeader(重写ResponseHeader)
- 23. RewriteResponseHeader(重写ResponseHeader)
- 24. SetStatus(设置响应状态码)
- 25. SaveSession(保存Session)
- 26. StripPrefix(删除路径前缀)
- 27. SetRequestSize(设置请求最大长度)
- 28. RequestHeaderSize(请求头最大长度)
- 29. RequestHeaderSize(请求头最大长度)
Spring Cloud Gateway 概述及工作原理
网关提供API全托管,丰富的API管理功能。包含协议适配、协议转发、安全策略(WAF)、限量、灰度发布等功能。
Spring Cloud Gateway:是基于Spring 5.0 开发的、Spring Boot 2.0 和 Project Reactor等技术开发的网关。
路由(Route)
路由是网关最基础的部分,路由信息由一个ID,一个目标URL、系列断言工厂和系列Filter组成。如果路由断言为真,则说明请求的URL和配置的路由匹配。
断言(Predicate)
Java8中的断言函数。Spring Cloud Gateway中的断言函数输入类型是Spring 5.0 框架中的ServerWebExchange。 Spring Cloud Gateway中的断言函数允许开发者定义匹配来自于Http请求中的任何信息。
过滤器(Filter)
过滤器分为两种:一种Gateway Filter(一般在每个路由中配置)和 Global Filter(作用于全部路由),过滤器将会对请求和响应进行修改。
工作原理图
Spring Cloud Gateway 工程
引入POM
<dependencies>
<!--网关服务-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--服务注册中心 客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
主程序代码
@SpringBootApplication
@EnableEurekaClient
public class GatewayApp {
public static void main(String[] args){
SpringApplication.run(GatewayApp.class,args);
}
}
代码创建路由
不管是配置还是代码创建都可以参考一下两个类:
GatewayFilterSpec(过滤器)
PredicateSpec(断言工厂)
@Component
public class RouteConfig {
@Bean
public RouteLocator customerRouteLocator(RouteLocatorBuilder builder){
return builder.routes().route("customer",
r -> r.path("/customer").and().after(ZonedDateTime.now())
.filters( f -> f.addRequestHeader("X-Token","token"))
.uri("http:127.0.0.1:8888/")).build();
}
}
配置路由
eureka:
client:
serviceUrl:
defaultZone: http://localhost:9001/eureka/
server:
port: 9002
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: customer
uri: lb://customer
#断言
predicates:
#可以采用 - Path 断言名称,=/customer/**:断言需要的参数
- Path=/customer/**
#可以采用 - Path 断言名称,=/customer/**:断言需要多个参数用,分开
- Header=X-Request-Id, \d+
#可以采用 -name (断言名称) args中填写参数信息
- name: Cookie
args:
name: X-Cookie
regexp: \d+
#过滤器
filters:
- RequestSize=500000
#作用于所有Routes
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
全局过滤器
全局过滤器,作用于全局所有路由。
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("custom global filter");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
断言(Predicate)
1. After(时间之后)
说明:当前时间大于配置时间,才能匹配通过
配置:- After=2022-06-20T17:42:47.789-07:00[America/Denver]
实现类:AfterRoutePredicateFactory
代码创建 after(ZonedDateTime datetime)
2. Before(时间之前)
说明:当前时间小于配置时间,才能匹配通过
配置:- Before =2022-012-20T17:42:47.789-07:00[America/Denver]
实现类:BeforeRoutePredicateFactory
代码创建 before(ZonedDateTime datetime)
3. Between(时间之间)
说明:当前时间在配置时间区间中,才能匹配通过
配置:-Between =2022-01-20T17:42:47.789-07:00[America/Denver], 2035-01-21T17:42:47.789-07:00[America/Denver]
实现类:BetweenRoutePredicateFactory,参数类型:ZonedDateTime
代码创建 between(ZonedDateTime datetime1, ZonedDateTime datetime2)
4. Cookie(Cookie中字段匹配)
说明:当Cookie中的key为(chocolate)的值(value)通过配置值的匹配
配置:- Cookie=chocolate, \s+
实现类:CookieRoutePredicateFactory
代码创建 cookie(String name, String regex)
5. Header(Header中字段匹配)
说明:当Header中的key为(X-Request-Id)的值通过配置值的匹配
配置:- Header=X-Request-Id, \d+
实现类:HeaderRoutePredicateFactory
代码创建 header(String header, String regex)或header(String header)
6. Host(Host匹配)
说明:当Host的值通过配置值的匹配
配置:- Host=.somehost.org,.anotherhost.org
实现类:HostRoutePredicateFactory
代码创建 host(String… pattern)
7. Method(Method请求方法匹配)
说明:当Method请求方法是配置值,通过匹配
配置:- Method=GET,POST
案例说明:当请求方法为GET或POST通过,其他不通过匹配。
实现类:MethodRoutePredicateFactory
代码创建 method(String… pattern)
8. Path(Path请求路径匹配)
说明:当Path请求路径,是配置值时,通过匹配。
配置:- Path=/red/{segment},/blue/{segment}
案例说明:如:http:127.0.0.1:8100/red/test。请求通过,http:127.0.0.1:8100/black/test。匹配不通过
实现类:PathRoutePredicateFactory
代码创建 path(String… pattern)或path(boolean matchOptionalTrailingSeparator, String… patterns)
9. Query(Query查询参数匹配)
说明:当请求中queryParams中参数匹配
配置:- Query=green
案例说明:不带值,只要查询参数中包含配置值即可,如果带值,则需要匹配值
实现类:QueryRoutePredicateFactory
代码创建 query(String param, String regex)或query(String param)
10. RemoteAddr(请求IP匹配)
说明:请求IP地址在网段之内或者相同的IP
配置:- RemoteAddr=192.168.1.1/24
案例说明:当前匹配IP地址范围192.168.1.1~192.168.255
实现类:RemoteAddrRoutePredicateFactory
代码创建 remoteAddr(RemoteAddressResolver resolver, String… addrs)或remoteAddr(String… addrs)
11. Weight(权重)
说明:用于相同组(group)中的路由,根据权重比进行转发
配置:- Weight=group1, 8
案例说明:当两个以上(含两个)Route配置的组相同,那么相同的请求会根据权重比转发。例如:实现恢复发布。
实现类:WeightRoutePredicateFactory
代码创建 weight(String group, int weight)
GatewayFilter(过滤器)
1. AddRequestHeader(请求头添加参数)
说明:在请求头中添加参数以及值
配置:- AddRequestHeader=X-Request-red, blue
案例说明:在请求Headers中添加Key和Value
实现类:AddRequestHeaderGatewayFilterFactory
代码创建 addRequestHeader(String headerName, String headerValue)
2. AddRequestParameter(Query)
说明:在请求头中添加参数以及值
配置:- AddRequestParameter=red, blue
案例说明:如:原数据:http:127.0.0.1:8100/customer, 更改为http:127.0.0.1:8100/customer?red=blue
实现类:AddRequestParameterGatewayFilterFactory
代码创建 addRequestParameter(String param, String value)
3. AddResponseHeader(响应头添加参数)
说明:在响应头中添加参数以及值
配置:- AddResponseHeader=X-Response-Red, Blue
案例说明:在响应Headers中添加Key和Value
实现类:AddResponseHeaderGatewayFilterFactory
代码创建 addResponseHeader(String headerName, String headerValue)
4. DedupeResponseHeader(响应头重复数据消除)
说明:响应头中同一个Key,存在多个重复数据,消除重复数据。
#消除Access-Control-Allow-Credentials和Access-Control-Allow-Origin中重复的数据。
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
#示例:消除前 Access-Control-Allow-Credentials:ture,false
#消除后 Access-Control-Allow-Credentials:ture
实现类:DedupeResponseHeaderGatewayFilterFactory
代码创建 dedupeResponseHeader(String headerName, String strategy)
5. Hystrix(熔断)
说明:熔断,是为了请求超时时,自动失败转到指定页面
#fallbackcmd的名称为Hystrix中异常的名称
#forward:为Hystrix异常时候的回调地址
- Hystrix=fallbackcmd,forward:/fallback
#或下面写法
-name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/fallback
hystrix
command
fallbackcmd
execution
isolation
thread
timeoutInMilliseconds:500
案例说明:当前请求超过500毫秒之后,会自动触发fallback的调用。
实现类:HystrixGatewayFilterFactory
代码创建 hystrix(Consumer<Config> configConsumer
6. RequestRateLimiter(请求限速)
说明:熔断,是为了请求超时时,自动失败转到指定页面
#fallbackcmd的名称为Hystrix中异常的名称
#forward:为Hystrix异常时候的回调地址
- name: RequestRateLimiter
args:
# 使用SpEL按名称引用bean
key-resolver: "#{@hostAddressKeyResolver}"
#详情参考RedisRateLimiter
#允许用户每秒处理多少请求, 默认值1
redis-rate-limiter.replenishRate: 5
#令牌捅的容量,允许在一秒内的完成的最大请求数, 默认值1
redis-rate-limiter.burstCapacity: 15
redis-rate-limiter.requestedTokens: 1
key-resolver的代码
@Bean("hostAddressKeyResolver")
public KeyResolver hostAddressKeyResolver(){
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
案例说明:当前请求超过500毫秒之后,会自动触发fallback的调用。
实现类:RequestRateLimiterGatewayFilterFactory
代码创建 requestRateLimiter(Consumer<org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory.Config> configConsumer)
7. RedirectTo(重定向)
说明:出现异常,重定向到指定URL。
状态码只能为3xx
。
配置:- RedirectTo=302, https://acme.org
案例说明:当请求返回状态码为302,重定向到指定URL。
实现类:RedirectToGatewayFilterFactory
代码创建 redirect(String status, String url)
8. RewritePath(重写路径)
说明:将请求路径更该为指定路径
配置:- RewritePath=/red/?(?<segment>.*), /${segment}
案例说明:将请求路径去除了/red
实现类:RedirectToGatewayFilterFactory
代码创建 rewritePath(String regex, String replacement)
9. CircuitBreaker(断路器)
说明:断路器,当请求返回的状态码,在断路器状态码中,会将请求转发到指定URL
#第一种:myCircuitBreaker 自定义异常
- CircuitBreaker=myCircuitBreaker
#第二种:配置,错误就转发
- CircuitBreaker=myCircuitBreaker,forward:/fallback
#第三种:其中fallbackUri执行反馈需要(试图)View
#statusCodes: 配置了状态,除了发送在fallbackcmd的异常会调用fallbackUri,
# 当返回状态为statusCodes中的状态也会调用fallbackUri
- name: CircuitBreaker
args:
name: fallbackcmd
fallbackUri: forward:/inCaseOfFailureUseThis
statusCodes:
- 500
hystrix
command
fallbackcmd
execution
isolation
thread
timeoutInMilliseconds:500
实现类:SpringCloudCircuitBreakerFilterFactory
代码创建 circuitBreaker(Consumer<org.springframework.cloud.gateway.filter.factory.SpringCloudCircuitBreakerFilterFactory.Config> configConsumer)
10. FallbackHeaders(回调头添加信息)
说明:当断路器,返回异常。可以通过当前过滤器添加请求头信息
配置了CircuitBreaker或Hystrix才能起作用
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
#断路器
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
#FallbackHeaders 只有配置了CircuitBreaker或Hystrix才能起作用
#用来获取异常信息,添加到返回头中。
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header
实现类:FallbackHeadersGatewayFilterFactory
代码创建 fallbackHeaders(org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory.Config config)或fallbackHeaders(Consumer<org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory.Config> configConsumer)
11. MapRequestHeader(请求头映射)
说明:如果请求头存在fromHeader,则将fromHeader值复制到toHeader
配置:- MapRequestHeader=Blue, X-Request-Red
实现类:MapRequestHeaderGatewayFilterFactory
代码创建 mapRequestHeader(String fromHeader, String toHeader)
12. PrefixPath(路径前缀)
说明:路径添加上配置的值,如果存在则不添加。
配置:- PrefixPath=/mypath
实现类:PrefixPathGatewayFilterFactory
代码创建 prefixPath(String prefix)
13. PreserveHostHeader(保留主机标头)
说明:保留主机标头信息
配置:- PreserveHostHeader
实现类:PreserveHostHeaderGatewayFilterFactory
代码创建 preserveHostHeader()
14. SetHostHeader(设置主机头)
说明:设置Header中Host的信息
配置:- SetHostHeader=127.0.0.1
说明:修改Header中Host的值为127.0.0.1
实现类:SetRequestHostHeaderGatewayFilterFactory
代码创建 setHostHeader(String hostName)
15. RemoveRequestHeader(删除RequestHeader信息)
说明:根据Key删除RequestHeader中的信息
配置:- RemoveRequestHeader=X-Name
说明:过滤前:Request Headers X-Name:age
过滤后:Request Headers
实现类:RemoveRequestHeaderGatewayFilterFactory
代码创建 removeRequestHeader(String headerName)
16. RemoveRequestParameter(删除请求参数)
说明:根据Key删除RequestParameter中的信息
配置:- RemoveRequestParameter=name
说明:过滤前:/test?name=张三&age=18
过滤后:/test?age=18
实现类:RemoveRequestParameterGatewayFilterFactory
代码创建 removeRequestParameter(String paramName)
17. RemoveResponseHeader(删除ResponseHeader参数)
说明:根据Key删除ResponseHeader中的信息
配置:- removeResponseHeader=name
说明:过滤前:Response Headers X-Name:age
过滤后:Response Headers
实现类:RemoveResponseHeaderGatewayFilterFactory
代码创建 removeResponseHeader(String headerName)
18. Retry(请求重试)
说明:根据配置的重试次数以及对应的其他信息
配置:- Retry=3
说明:请求重试三次,则触发异常配置:
this.series = RetryGatewayFilterFactory.toList(Series.SERVER_ERROR);
this.statuses = new ArrayList();
this.methods = RetryGatewayFilterFactory.toList(HttpMethod.GET);
this.exceptions = RetryGatewayFilterFactory.toList(IOException.class, TimeoutException.class);
实现类:RetryGatewayFilterFactory
代码创建 retry(int retries)或retry(Consumer<RetryConfig> retryConsumer)
18. SecureHeaders(安全Headers信息)
说明:如果开启了对应的安全信息,则添加到Headers中。
配置:- SecureHeaders
实现类:SecureHeadersGatewayFilterFactory
代码创建 secureHeaders()或secureHeaders(Consumer<org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory.Config> configConsumer)
19. SetPath(设置Path)
说明:重新设置请求Path
#断言
predicates:
#匹配地址为/red/xxx,
- Path=/red/{segment}
filters:
#过滤前如:/red/max,过滤后:/max
- SetPath=/{segment}
实现类:SetPathGatewayFilterFactory
代码创建 setPath(String template)
20. SetRequestHeader(设置RequestHeaders信息)
说明:设置请求头的Key值为指定值
配置:- SetRequestHeader=X-Request-Red, Blue
说明:X-Request-Red:1234 修改为 X-Request-Red:Blue
实现类:SetRequestHeaderGatewayFilterFactory
代码创建 setRequestHeader(String headerName, String headerValue)
21. SetResponseHeader(设置ResponseHeader信息)
说明:设置响应头的Key值为指定值
配置:- SetResponseHeader=X-Request-Red, Blue
说明:X-Request-Red:1234 修改为 X-Request-Red:Blue
实现类:SetResponseHeaderGatewayFilterFactory
代码创建 setResponseHeader(String headerName, String headerValue)
22. RewriteResponseHeader(重写ResponseHeader)
说明:重写响应头中的信息,Key中的值,根据正则匹配,替换为指定参数
配置:-RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
说明:X-Request-Red:password=xxdw &age=18修改为 X-Request-Red:password=***&age=18
实现类:RewriteResponseHeaderGatewayFilterFactory
代码创建 rewriteResponseHeader(String headerName, String regex, String replacement)
23. RewriteResponseHeader(重写ResponseHeader)
说明:重写响应头中Location的值,修改为当路由的URI的值
配置:- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
说明:如:当前URI=127.0.0.1, 返回的Localhost为 10.0.0.1/test。修改为127.0.0.1
实现类:RewriteLocationResponseHeaderGatewayFilterFactory
代码创建 rewriteLocationResponseHeader(String stripVersionMode, String locationHeaderName, String hostValue, String protocolsRegex)
24. SetStatus(设置响应状态码)
说明:设置响应状态码
配置:- SetStatus=401
说明:当前响应的状态码为401
实现类:SetStatusGatewayFilterFactory
代码创建 setStatus(int status)或setStatus(HttpStatus status)或setStatus(String status)
25. SaveSession(保存Session)
说明:保存Session会话信息
配置:- SaveSession
说明:保存会话信息,已方便后续请求。
实现类:SaveSessionGatewayFilterFactory
代码创建 saveSession()
26. StripPrefix(删除路径前缀)
说明:删除路径前缀,以/为分割福。
配置:- StripPrefix=1
说明:/test/age/1 修改后 /age/1
实现类:StripPrefixGatewayFilterFactory
代码创建 stripPrefix(int parts)
27. SetRequestSize(设置请求最大长度)
说明:content-length中的大小要小于配置的值
配置:- SetRequestSize=5000000L
说明:默认大小5000000L
实现类:RequestSizeGatewayFilterFactory
代码创建 setRequestSize(Long size)或setRequestSize(DataSize size)
28. RequestHeaderSize(请求头最大长度)
说明:请求头中所有数据最大长度
配置:- RequestHeaderSize=1000B
说明:默认大小16000B
实现类:RequestHeaderSizeGatewayFilterFactory
代码创建 setRequestHeaderSize(DataSize size)
29. RequestHeaderSize(请求头最大长度)
说明:请求头中所有数据最大长度
配置:- RequestHeaderSize=1000B
说明:默认大小16000B
实现类:RequestHeaderSizeGatewayFilterFactory
代码创建 setRequestHeaderSize(DataSize size)