Spring Cloud Gateway 文档
Spring Cloud GatewaySpring Cloud Gateway1.1 简介内置的过滤器工厂4.1快捷配置4.2 完全扩展的参数5.Rote Predicate Factories 路由断言5.1After Rote Predicate 在断言之后5.2 Before Rote Predicate 在断言之前5.3 Between Route 中间The Cookie Route
目录
5.Rote Predicate Factories 路由断言
5.2 Before Rote Predicate 在断言之前
The Header Route Predicate 断言使用header
5.6 The Host Route Predicate 断言使用host
5.7 The Method Route Predicate
5.8. The Path Route Predicate Factory 路径断言
5.9. The Query Route Predicate Factory 查询断言
5.10. The RemoteAddr Route Predicate Factory 远程路径
5.11. The Weight Route Predicate Factory 权重
5.11.1. Modifying the Way Remote Addresses Are Resolved
6.GatewayFilter Factories 网关过滤
6.1 The AddRequestHeader GatewayFilter Factory
6.2 The AddRequestParameter GatewayFilter Factory
6.3 The AddResponseHeader GatewayFilter Factory 响应头
6.4The DedupeResponseHeader GatewayFilter Factory 过滤重复响应头
6.5 The Hystrix GatewayFilter Factory 熔断
6.6. Spring Cloud CircuitBreaker GatewayFilter Factory
6.6.1. Tripping The Circuit Breaker On Status Codes 返回状态
6.7. The FallbackHeaders GatewayFilter Factory
6.8 The MapRequestHeader GatewayFilter Factory
6.9 The PrefixPath GatewayFilter Factory 路径前缀
6.10 The PreserveHostHeader GatewayFilter Factory
6.11. The RequestRateLimiter GatewayFilter Factory 请求速率限制
spring cloud gateway 自带了个限流器filter,就是RequestRateLimiter,可以使用令牌桶算法来限流
首先看下spring cloud gateway的配置,注意要用到redis
这个key resolver会生成一个key,为这个key生成一个令牌桶。如果是客户端ip,那么就是为每个ip生成一个令牌桶。如果是个固定值,就是全局的令牌桶。
6.12 The RedirectTo GatewayFilter Factory 重定向
6.13 The RevoveRequestHeader GatewayFilter Factory
6.14 RemoveResponseHeader Gateway Factory
6.15 The RemoveRequestParamter GatewayFilter Factory
6.16 The RewritePath GatewayFilter Factory 重写路径
6.18 RewriteLocationResonseHeader GateWayFilter Factory 重写响应头中 Location 的值
6.18. The RewriteResponseHeader GatewayFilter Factory
6.19. The SaveSession GatewayFilter Factory
6.20. The SecureHeader GatewayFilter Factory unknow
6.21 The SetPath GatewayFilter Factory 修改路径
6.22 The SetRequestHeader GatewayFilter Factory
6.23. The SetResponseHeader GatewayFilter Factory 设置响应头
6.24 The SetStatus GatewayFilter Factory
6.25 The StripPrefix GatewayFilter Factory 剥离路径
6.26. The Retry GatewayFilter Factory 重试
6.27. The RequestSize GatewayFilter Factory
6.28. The SetRequestHostHeader GatewayFilter Factory
6.29. Modify a Request Body GatewayFilter Factory 修改请求体
6.30. Modify a Response Body GatewayFilter Factory 想改响应体
7.1 Combined Global Filter and GatewayFilter Ordering 组合全局过滤器和网关过滤器排序
7.3. The LoadBalancerClient Filter
7.4. The ReactiveLoadBalancerClientFilter
7.5.The Netty Routing Filter --了解
7.6. The Netty Write Response Filter 将代理响应写回网关的客户端侧--了解
7.7. The RouteToRequestUrl Filter --将从request里获取的原始url转换成Gateway进行请求转发时所使用的url
7.8. The Websocket Routing Filter --- 使用Spring Web Socket将转发 Websocket 请求
7.9. The Gateway Metrics Filter 监控指标
1.1 简介
SpringCloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。
SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 2.0之前的非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
Spring Cloud Gateway 的目标,不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
提前声明:Spring Cloud Gateway 底层使用了高性能的通信框架Netty。
1.引入Geteway
<span style="background-color:#f8f8f8"><span style="color:#333333"><dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency></span></span>
如不想启用网关,则配置
spring.cloud.gateway.enabled=false
.
Spring Cloud Gateway is built on Spring Boot 2.x, Spring WebFlux, and Project Reactor.
术语:
Route:路由 The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates, and a collection of filters. A route is matched if the aggregate predicate is true.
Predicate:断言 This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange
. This lets you match on anything from the HTTP request, such as headers or parameters.
Filter:过滤器
3.工作流程
Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a route, it is sent to the Gateway Web Handler. This handler runs the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line is that filters can run logic both before and after the proxy request is sent. All “pre” filter logic is executed. Then the proxy request is made. After the proxy request is made, the “post” filter logic is run.
配置:
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
application:
name: gateway
cloud:
nacos:
config:
server-addr: 172.16.102.215:12100
file-extension: yaml
namespace: dd229d69-1788-4800-b511-c646bb140dd7
group: DEFAULT_GROUP
prefix: gateway
refresh-enabled: true
gateway:
discovery:
locator:
enabled: false # 与服务注册与发现组件结合,设置为 true 后;id默认为微服务名称xxx-server;
#gatewayapplication有feign自动做负载均衡; 不需要定制化显式配置;已生成默认的id=xservice,uri: lb://xserver , path=/serviceId/**
routes:
- id: 1
uri: http://www.baidu.com/
predicates:
- Path=/model/**
filters:
- StripPrefix=1 #表示在将请求发送到下游之前从请求中剥离的路径个数。
- name: RequestRateLimiter #请求数据限流, 名称不能随便写
args:
key-resolver: '#{@urlKeyResolver}'
redis-rate-limiter.replenishRate: 300 #令牌桶每秒填充平均速率
redis-rate-limiter.burstCapacity: 600 #令牌桶总容量</span></span>
内置的过滤器工厂
这里简单将Spring Cloud Gateway内置的所有过滤器工厂整理成了一张表格,虽然不是很详细,但能作为速览使用。如下:
过滤器工厂 | 作用 | 参数 |
---|---|---|
AddRequestHeader | 为原始请求添加Header | Header的名称及值 |
AddRequestParameter | 为原始请求添加请求参数 | 参数名称及值 |
AddResponseHeader | 为原始响应添加Header | Header的名称及值 |
DedupeResponseHeader | 剔除响应头中重复的值 | 需要去重的Header名称及去重策略 |
Hystrix | 为路由引入Hystrix的断路器保护 | HystrixCommand 的名称 |
FallbackHeaders | 为fallbackUri的请求头中添加具体的异常信息 | Header的名称 |
PrefixPath | 为原始请求路径添加前缀 | 前缀路径 |
PreserveHostHeader | 为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host | 无 |
RequestRateLimiter | 用于对请求限流,限流算法为令牌桶 | keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus |
RedirectTo | 将原始请求重定向到指定的URL | http状态码及重定向的url |
RemoveHopByHopHeadersFilter | 为原始请求删除IETF组织规定的一系列Header | 默认就会启用,可以通过配置指定仅删除哪些Header |
RemoveRequestHeader | 为原始请求删除某个Header | Header名称 |
RemoveResponseHeader | 为原始响应删除某个Header | Header名称 |
RewritePath | 重写原始的请求路径 | 原始路径正则表达式以及重写后路径的正则表达式 |
RewriteResponseHeader | 重写原始响应中的某个Header | Header名称,值的正则表达式,重写后的值 |
SaveSession | 在转发请求之前,强制执行WebSession::save 操作 | 无 |
SecureHeaders | 为原始响应添加一系列起安全作用的响应头 | 无,支持修改这些安全响应头的值 |
SetPath | 修改原始的请求路径 | 修改后的路径 |
SetResponseHeader | 修改原始响应中某个Header的值 | Header名称,修改后的值 |
SetStatus | 修改原始响应的状态码 | HTTP 状态码,可以是数字,也可以是字符串 |
StripPrefix | 用于截断原始请求的路径 | 使用数字表示要截断的路径的数量 |
Retry | 针对不同的响应进行重试 | retries、statuses、methods、series |
RequestSize | 设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返回 413 Payload Too Large | 请求包大小,单位为字节,默认值为5M |
ModifyRequestBody | 在转发请求之前修改原始请求体内容 | 修改后的请求体内容 |
ModifyResponseBody | 修改原始响应体的内容 | 修改后的响应体内容 |
Default | 为所有路由添加过滤器 | 过滤器工厂名称及值 |
SetRequestHeader | 增加请求header | |
RequestSize | 请求量 |
。
uri 配置方式:
4.1快捷配置
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue #多个条件使用,</span></span>
4.2 完全扩展的参数
扩展的参数通常会有一个name,一个args ,args 通常是配置过滤器键值对
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue</span></span>
5.Rote Predicate Factories 路由断言
5.1After Rote Predicate 在断言之后
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]</span></span>
5.2 Before Rote Predicate 在断言之前
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]</span></span>
5.3 Between Route 中间
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]</span></span>
The Cookie Route Predicate 使用cookie
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p</span></span>
The Header Route Predicate 断言使用header
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+</span></span>
5.6 The Host Route Predicate 断言使用host
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org</span></span>
5.7 The Method Route Predicate
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST</span></span>
5.8. The Path Route Predicate Factory 路径断言
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}</span></span>
跳转之后的链接为https://example.org/red/{segment}
<span style="background-color:#f8f8f8"><span style="color:#333333">// 获取请求参数
Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");</span></span>
5.9. The Query Route Predicate Factory 查询断言
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green</span></span>
<span style="background-color:#f8f8f8"><span style="color:#333333">## 请求参数red=gree 时才匹配,会成功转发
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree</span></span>
5.10. The RemoteAddr Route Predicate Factory 远程路径
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24</span></span>
5.11. The Weight Route Predicate Factory 权重
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
#This route would forward ~80% of traffic to weighthigh.org and ~20% of traffic to weighlow.org</span></span>
5.11.1. Modifying the Way Remote Addresses Are Resolved
<span style="background-color:#f8f8f8"><span style="color:#333333">RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
.maxTrustedIndex(1);
...
.route("direct-route",
r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
.uri("https://downstream1")
.route("proxied-route",
r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
.uri("https://downstream2")
)</span></span>
6.GatewayFilter Factories 网关过滤
6.1 The AddRequestHeader GatewayFilter Factory
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue</span></span>
header 中添加参数传参
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{segment}
# 动态传参</span></span>
6.2 The AddRequestParameter GatewayFilter Factory
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
#通过url 传参,相当于?red=blue</span></span>
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddRequestParameter=foo, bar-{segment}</span></span>
6.3 The AddResponseHeader GatewayFilter Factory 响应头
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
#返回结果header
X-Response-Red →Blue</span></span>
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddResponseHeader=foo, bar-{segment}</span></span>
6.4The DedupeResponseHeader GatewayFilter Factory 过滤重复响应头
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_FIRST
#剔除重复响应头,多个以空格隔开
RETAIN_FIRST: 默认值,保留第一个值
RETAIN_LAST: 保留最后一个值
RETAIN_UNIQUE: 保留所有唯一值,以它们第一次出现的顺序保留</span></span>
6.5 The Hystrix GatewayFilter Factory 熔断
Hystrix:断路器
开启断路器功能,需添加hystrix的相关依赖
<span style="background-color:#f8f8f8"><span style="color:#333333"><dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency></span></span>
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: https://example.org
filters:
- Hystrix=myCommandName</span></span>
自定义
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingserviceendpoint
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/fallback
- RewritePath=/consumingserviceendpoint, /backingserviceendpoint</span></span>
<span style="background-color:#f8f8f8"><span style="color:#333333">@GetMapping("/fallback")
public Object fallback() {
Map<String,Object> result = new HashMap<>(3);
result.put("data",null);
result.put("message","request fallback!!!");
result.put("code",500);
return result;
}</span></span>
也可以直接请求断路器,不影响正常跳转
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
</span></span>
配置熔断器时间测试该配置不行,暂时不知道原因
<span style="background-color:#f8f8f8"><span style="color:#333333">hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000</span></span>
6.6. Spring Cloud CircuitBreaker GatewayFilter Factory
CircuitBreaker: 短路器
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/red
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
- RewritePath=/red, /blue
# RewritePath=/red(?<segment>/?.*), $\{segment} 动态参数</span></span>
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint
重写路径
/red/123 => /blue/123
java 配置如下
<span style="background-color:#f8f8f8"><span style="color:#333333">@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis"))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
.build();
}</span></span>
<span style="background-color:#f8f8f8"><span style="color:#333333">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</span></span>
6.6.1. Tripping The Circuit Breaker On Status Codes 返回状态
根据返回的状态码,解除短路器
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
statusCodes:
- 500
- "NOT_FOUND"</span></span>
<span style="background-color:#f8f8f8"><span style="color:#333333">@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis").addStatusCode("INTERNAL_SERVER_ERROR"))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
.build();
}</span></span>
6.7. The FallbackHeaders GatewayFilter Factory
<span style="background-color:#f8f8f8"><span style="color:#333333">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:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header</span></span>
-
executionExceptionTypeHeaderName
("Execution-Exception-Type"
) -
executionExceptionMessageHeaderName
("Execution-Exception-Message"
) -
rootCauseExceptionTypeHeaderName
("Root-Cause-Exception-Type"
) -
rootCauseExceptionMessageHeaderName
("Root-Cause-Exception-Message"
)
6.8 The MapRequestHeader GatewayFilter Factory
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red</span></span>
在header添加参数,映射,fromHeaderand
toHeader
返回值:
xRequestRed:2222222,12321312 Blue:12321312
6.9 The PrefixPath GatewayFilter Factory 路径前缀
PrefixPath:前缀
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath</span></span>
请求hello 转发为 /mypath/hello
6.10 The PreserveHostHeader GatewayFilter Factory
The PreserveHostHeader
GatewayFilter
factory has no parameters.
为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader</span></span>
6.11. The RequestRateLimiter GatewayFilter Factory 请求速率限制
rate:速率
determine :确定
The RequestRateLimiter
GatewayFilter
factory uses a RateLimiter
implementation to determine if the current request is allowed to proceed. If it is not, a status of HTTP 429 - Too Many Requests
(by default) is returned.
详细使用流程:
spring cloud gateway 自带了个限流器filter,就是RequestRateLimiter,可以使用令牌桶算法来限流
先说下令牌桶算法,就是:每秒向令牌桶放N个令牌,令牌桶的最大容积是M个,那么如果请求过来了,会从令牌桶中拿出一个令牌,令牌桶还剩M-1个。以此类推,当令牌桶的数量还剩0个的时候,就拒绝接受请求。所以这个情况可以支持突发性的请求情况。就是我一致很小量的请求,但是突然来了一大波请求,令牌桶容积决定了它能接受的最大突发情况。
首先看下spring cloud gateway的配置,注意要用到redis
<span style="background-color:#f8f8f8"><span style="color:#333333"> - id: lb2thorquest
uri: lb://THORQUEST
order: 9999
predicates:
- Host=10.1.0.75:9001
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 # 令牌桶放入的速度
redis-rate-limiter.burstCapacity: 3 # 令牌桶的容积
key-resolver: "#{@remoteAddrKeyResolver}" #SPEL表达式去的对应的bean
redis:
host: 10.10.2.175
port: 6379
database: 5</span></span>
引入redis
<span style="background-color:#f8f8f8"><span style="color:#333333"> <span style="color:#117700"><</span><span style="color:#117700">dependency</span><span style="color:#117700">></span>
<span style="color:#117700"><</span><span style="color:#117700">groupId</span><span style="color:#117700">></span>org.springframework.boot<span style="color:#117700"></</span><span style="color:#117700">groupId</span><span style="color:#117700">></span>
<span style="color:#117700"><</span><span style="color:#117700">artifactId</span><span style="color:#117700">></span>spring-boot-starter-data-redis-reactive<span style="color:#117700"></</span><span style="color:#117700">artifactId</span><span style="color:#117700">></span>
<span style="color:#117700"></</span><span style="color:#117700">dependency</span><span style="color:#117700">></span></span></span>
这个key resolver会生成一个key,为这个key生成一个令牌桶。如果是客户端ip,那么就是为每个ip生成一个令牌桶。如果是个固定值,就是全局的令牌桶。
<span style="background-color:#f8f8f8"><span style="color:#333333"> <span style="color:#555555">@Bean</span>
<span style="color:#000000">KeyResolver</span> <span style="color:#0000ff">remoteAddrKeyResolver</span>() {
<span style="color:#770088">return</span> <span style="color:#000000">exchange</span> <span style="color:#981a1a">-></span> <span style="color:#000000">Mono</span>.<span style="color:#000000">just</span>(<span style="color:#000000">Objects</span>.<span style="color:#000000">requireNonNull</span>(<span style="color:#000000">exchange</span>.<span style="color:#000000">getRequest</span>().<span style="color:#000000">getRemoteAddress</span>()).<span style="color:#000000">getHostName</span>());
}</span></span>
那么使劲刷新url,出现429 too many request 就表示成功了,
By default, if the KeyResolver
does not find a key, requests are denied. You can adjust this behavior by setting the spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key
(true
or false
) and spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code
properties.
The RequestRateLimiter is not configurable with the "shortcut" notation. The following example below is invalid:Example 35. application.properties# INVALID SHORTCUT CONFIGURATION spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver} | |
---|---|
6.11.1 The Redis RateLimiter
he Redis implementation is based off of work done at Stripe. It requires the use of the spring-boot-starter-data-redis-reactive
Spring Boot starter.
要求添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency>
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 #令牌桶放入的速度
redis-rate-limiter.burstCapacity: 20 #令牌桶的容积
redis-rate-limiter.requestedTokens: 1 #一个请求需要几个令牌,默认是1
</span></span>
replenishRate=1
, requestedTokens=60
and burstCapacity=60
will result in a limit of 1 request/min
.
<span style="background-color:#f8f8f8"><span style="color:#333333">@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}</span></span>
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}" 需先定义
key-resolver: "#{@userKeyResolver}" 需先定义</span></span>
6.12 The RedirectTo GatewayFilter Factory 重定向
The RedirectTo
GatewayFilter
factory takes two parameters, status
and url
.
有两个参数 status ,url
The status
parameter should be a 300 series redirect HTTP code, such as 301. The url
parameter should be a valid URL.
status 参数应该是300系列 重定向 http code,像301 ,url 应该是个有效的url
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org</span></span>
状态码:
已定义范围 | 分类 | |
---|---|---|
1XX | 100-101 | 信息提示 |
2XX | 200-206 | 成功 |
3XX | 300-305 | 重定向 |
4XX | 400-415 | 客户端错误 |
5XX | 500-505 | 服务器错误 |
6.13 The RevoveRequestHeader GatewayFilter Factory
The RemoveRequestHeader
GatewayFilter
factory takes a name
parameter. It is the name of the header to be removed.
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo #移除header X-Request-Foo</span></span>
6.14 RemoveResponseHeader Gateway Factory
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo #移除响应头 X-Response-Foo</span></span>
6.15 The RemoveRequestParamter GatewayFilter Factory
The RemoveRequestParameter
GatewayFilter
factory takes a name
parameter. It is the name of the query parameter to be removed. The following example configures a RemoveRequestParameter
GatewayFilter
:
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red #移除请求参数 red</span></span>
6.16 The RewritePath GatewayFilter Factory 重写路径
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red(?<segment>/?.*), $\{segment}</span></span>
重写路径
/red/blue => /blue/red
6.18 RewriteLocationResonseHeader GateWayFilter Factory 重写响应头中 Location 的值
不太懂
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://hxmec.com
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
如上所示,一个请求 POST api.anoyi.com/some/object/name, Response header Location 的值 prod.anoyi.com/v2/some/object/id 将被改为 api.anoyi.com/some/object/id</span></span>
参数 stripVersionMode 可选值如下:
NEVER_STRIP:版本信息不会被剥离,即使原始请求路径不包含版本 AS_IN_REQUEST:仅当原始请求路径不包含任何版本时,才会剥离版本【默认】 ALWAYS_STRIP:即使原始请求路径包含版本,也会剥离版本 参数 hostValue,如果提供,会替换 Response Header Location 值中的 host:port 部分;如果不提供,则会使用 Request 的 Host 作为默认值 参数 protocolRegex,协议会与该值匹配,如果不匹配,过滤器不回做任何操作,默认值 http|https|ftp|ftps
6.18. The RewriteResponseHeader GatewayFilter Factory
RewriteResponseHeader 重写原始响应中的某个Header Header名称,值的正则表达式,重写后的值
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***</span></span>
<span style="background-color:#f8f8f8"><span style="color:#333333">response.setHeader("X-Response-Red", "/42?user=ford&password=omg!what&flag=true");</span></span>
6.19. The SaveSession GatewayFilter Factory
保存 Session,在向下游服务转发请求之前强制执行 WebSession::save操作
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession</span></span>
如果将 Spring Security 与 Spring Session 集成,并希望确保安全性详细信息已转发到远程进程,那么这一点至关重要。
6.20. The SecureHeader GatewayFilter Factory unknow
SecureHeaders会向响应添加多个头数据,主要是根据这篇博客的建议:Everything you need to know about HTTP security headers。 会添加下面这些头,括号中是默认值。
X-Xss-Protection:1 (mode=block) Strict-Transport-Security (max-age=631138519) X-Frame-Options (DENY) `X-Content-Type-Options (nosniff) Referrer-Policy (no-referrer) Content-Security-Policy (default-src ‘self’ https:; font-src ‘self’ https: data:; img-src ‘self’ https: data:; object-src ‘none’; script-src https:; style-src ‘self’ https: ‘unsafe-inline’) X-Download-Options (noopen) X-Permitted-Cross-Domain-Policies (none) 若要改变这些默认值,在 spring.cloud.gateway.filter.secure-headers命名空间中设置适当的值。下面这些属性可设置: xss-protection-header strict-transport-security x-frame-options x-content-type-options referrer-policy content-security-policy x-download-options x-permitted-cross-domain-policies 这些属性是与上面列出要添加的头是对应的,在 SecureHeadersProperties.java 安全头属性类文件中可以看到。 要禁用默认值,设置spring.cloud.gateway.filter.secure-headers.disable属性,值使用逗号分隔符(,)。注意,值必须是安全标头(secure headers)的小写全名。如下所示: spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
6.21 The SetPath GatewayFilter Factory 修改路径
SetPath 修改原始的请求路径 修改后的路径
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}</span></span>
For a request path of /red/blue
, this sets the path to /blue
before making the downstream request.
6.22 The SetRequestHeader GatewayFilter Factory
有两个参数 name , value
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}</span></span>
6.23. The SetResponseHeader GatewayFilter Factory 设置响应头
有两个参数 name ,value
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}</span></span>
6.24 The SetStatus GatewayFilter Factory
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: https://example.org
filters:
- SetStatus=BAD_REQUEST
- id: setstatusint_route
uri: https://example.org
filters:
- SetStatus=401</span></span>
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status</span></span>
6.25 The StripPrefix GatewayFilter Factory 剥离路径
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2 </span></span>
When a request is made through the gateway to /name/blue/red
, the request made to nameservice
looks like nameservice/red
.
6.26. The Retry GatewayFilter Factory 重试
The Retry
GatewayFilter
factory supports the following parameters:
-
retries
: The number of retries that should be attempted. -
statuses
: The HTTP status codes that should be retried, represented by usingorg.springframework.http.HttpStatus
. -
methods
: The HTTP methods that should be retried, represented by usingorg.springframework.http.HttpMethod
. -
series
: The series of status codes to be retried, represented by usingorg.springframework.http.HttpStatus.Series
. -
exceptions
: A list of thrown exceptions that should be retried. -
backoff
: The configured exponential backoff for the retries. Retries are performed after a backoff interval offirstBackoff * (factor ^ n)
, wheren
is the iteration. IfmaxBackoff
is configured, the maximum backoff applied is limited tomaxBackoff
. IfbasedOnPreviousValue
is true, the backoff is calculated byusingprevBackoff * factor
.
The following defaults are configured for Retry
filter, if enabled:
-
retries
: Three times -
series
: 5XX series -
methods
: GET method -
exceptions
:IOException
andTimeoutException
-
backoff
: disabled
The following listing configures a Retry GatewayFilter
:
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: retry_test
uri: http://localhost:8080/flakey
predicates:
- Host=*.retry.com
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
methods: GET,POST
exceptions: java.lang.RuntimeException #需写类名,否则转换不了,报错
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false</span></span>
6.27. The RequestSize GatewayFilter Factory
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000</span></span>
6.28. The SetRequestHostHeader GatewayFilter Factory
certain 某些
situation : 情况
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: set_request_host_header_route
uri: http://localhost:8080/headers
predicates:
- Path=/headers
filters:
- name: SetRequestHostHeader
args:
host: example.org</span></span>
The SetRequestHostHeader
GatewayFilter
factory replaces the value of the host header with example.org
. 替换host
6.29. Modify a Request Body GatewayFilter Factory 修改请求体
You can use the ModifyRequestBody
filter filter to modify the request body before it is sent downstream by the gateway.
This filter can be configured only by using the Java DSL. | |
---|---|
The following listing shows how to modify a request body GatewayFilter
:
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#555555">@Bean</span>
<span style="color:#770088">public</span> <span style="color:#000000">RouteLocator</span> <span style="color:#0000ff">routes</span>(<span style="color:#000000">RouteLocatorBuilder</span> <span style="color:#000000">builder</span>) {
<span style="color:#770088">return</span> <span style="color:#000000">builder</span>.<span style="color:#000000">routes</span>()
.<span style="color:#000000">route</span>(<span style="color:#aa1111">"rewrite_request_obj"</span>, <span style="color:#000000">r</span> <span style="color:#981a1a">-></span> <span style="color:#000000">r</span>.<span style="color:#000000">host</span>(<span style="color:#aa1111">"*.rewriterequestobj.org"</span>)
.<span style="color:#000000">filters</span>(<span style="color:#000000">f</span> <span style="color:#981a1a">-></span> <span style="color:#000000">f</span>.<span style="color:#000000">prefixPath</span>(<span style="color:#aa1111">"/httpbin"</span>)
.<span style="color:#000000">modifyRequestBody</span>(<span style="color:#008855">String</span>.<span style="color:#770088">class</span>, <span style="color:#000000">Hello</span>.<span style="color:#770088">class</span>, <span style="color:#000000">MediaType</span>.<span style="color:#000000">APPLICATION_JSON_VALUE</span>,
(<span style="color:#000000">exchange</span>, <span style="color:#000000">s</span>) <span style="color:#981a1a">-></span> <span style="color:#770088">return</span> <span style="color:#000000">Mono</span>.<span style="color:#000000">just</span>(<span style="color:#770088">new</span> <span style="color:#000000">Hello</span>(<span style="color:#000000">s</span>.<span style="color:#000000">toUpperCase</span>())))).<span style="color:#000000">uri</span>(<span style="color:#000000">uri</span>))
.<span style="color:#000000">build</span>();
}
<span style="color:#770088">static</span> <span style="color:#770088">class</span> <span style="color:#0000ff">Hello</span> {
<span style="color:#008855">String</span> <span style="color:#000000">message</span>;
<span style="color:#770088">public</span> <span style="color:#000000">Hello</span>() { }
<span style="color:#770088">public</span> <span style="color:#000000">Hello</span>(<span style="color:#008855">String</span> <span style="color:#000000">message</span>) {
<span style="color:#770088">this</span>.<span style="color:#000000">message</span> <span style="color:#981a1a">=</span> <span style="color:#000000">message</span>;
}
<span style="color:#770088">public</span> <span style="color:#008855">String</span> <span style="color:#000000">getMessage</span>() {
<span style="color:#770088">return</span> <span style="color:#000000">message</span>;
}
<span style="color:#770088">public</span> <span style="color:#008855">void</span> <span style="color:#000000">setMessage</span>(<span style="color:#008855">String</span> <span style="color:#000000">message</span>) {
<span style="color:#770088">this</span>.<span style="color:#000000">message</span> <span style="color:#981a1a">=</span> <span style="color:#000000">message</span>;
}
}</span></span>
if the request has no body, the RewriteFilter will be passed null . Mono.empty() should be returned to assign a missing body in the request. | |
---|---|
6.30. Modify a Response Body GatewayFilter Factory 想改响应体
<span style="background-color:#f8f8f8"><span style="color:#333333">@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyResponseBody(String.class, String.class,
(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri))
.build();
}</span></span>
6.31. Default Filter 默认过滤
To add a filter and apply it to all routes, you can use spring.cloud.gateway.default-filters
. This property takes a list of filters. The following listing defines a set of default filters:
Example 58. application.yml
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin</span></span>
7. Global Filters 全局过滤
7.1 Combined Global Filter and GatewayFilter Ordering 组合全局过滤器和网关过滤器排序
Combined: 结合
When a request matches a route, the filtering web handler adds all instances of GlobalFilter
and all route-specific instances of GatewayFilter
to a filter chain. This combined filter chain is sorted by the org.springframework.core.Ordered
interface, which you can set by implementing the getOrder()
method.
As Spring Cloud Gateway distinguishes between “pre” and “post” phases for filter logic execution (see How it Works), the filter with the highest precedence is the first in the “pre”-phase and the last in the “post”-phase.
<span style="background-color:#f8f8f8"><span style="color:#333333">@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;
}
}</span></span>
7.2. Foward Routing Filter
The ForwardRoutingFilter
looks for a URI in the exchange attribute ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
. If the URL has a forward
scheme (such as forward:///localendpoint
), it uses the Spring DispatcherHandler
to handle the request. The path part of the request URL is overridden with the path in the forward URL. The unmodified original URL is appended to the list in the ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
attribute.
7.3. The LoadBalancerClient Filter
LoadBalancerClient Filter | 整合Ribbon实现负载均衡 |
---|---|
url 使用服务代替
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**</span></span>
7.4. The ReactiveLoadBalancerClientFilter
The ReactiveLoadBalancerClientFilter
looks for a URI in the exchange attribute named ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
. If the URL has a lb
scheme (such as lb://myservice
), it uses the Spring Cloud ReactorLoadBalancer
to resolve the name (myservice
in this example) to an actual host and port and replaces the URI in the same attribute. The unmodified original URL is appended to the list in the ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
attribute. The filter also looks in the ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
attribute to see if it equals lb
. If so, the same rules apply. The following listing configures a ReactiveLoadBalancerClientFilter
:
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**</span></span>
By default, when a service instance cannot be found by the ReactorLoadBalancer
, a 503
is returned. You can configure the gateway to return a 404
by setting spring.cloud.gateway.loadbalancer.use404=true
.
The isSecure value of the ServiceInstance returned from the ReactiveLoadBalancerClientFilter overrides the scheme specified in the request made to the Gateway. For example, if the request comes into the Gateway over HTTPS but the ServiceInstance indicates it is not secure, the downstream request is made over HTTP . The opposite situation can also apply. However, if GATEWAY_SCHEME_PREFIX_ATTR is specified for the route in the Gateway configuration, the prefix is stripped and the resulting scheme from the route URL overrides the ServiceInstance configuration. | |
---|---|
7.5.The Netty Routing Filter --了解
使用Netty的 HttpClient 转发http、https请求 ----------- 了解
The Netty routing filter runs if the URL located in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange attribute has a http
or https
scheme. It uses the Netty HttpClient
to make the downstream proxy request. The response is put in the ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
exchange attribute for use in a later filter. (There is also an experimental WebClientHttpRoutingFilter
that performs the same function but does not require Netty.)
7.6. The Netty Write Response Filter 将代理响应写回网关的客户端侧--了解
The NettyWriteResponseFilter
runs if there is a Netty HttpClientResponse
in the ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
exchange attribute. It runs after all other filters have completed and writes the proxy response back to the gateway client response. (There is also an experimental WebClientWriteResponseFilter
that performs the same function but does not require Netty.)
7.7. The RouteToRequestUrl Filter --将从request里获取的原始url转换成Gateway进行请求转发时所使用的url
If there is a Route
object in the ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR
exchange attribute, the RouteToRequestUrlFilter
runs. It creates a new URI, based off of the request URI but updated with the URI attribute of the Route
object. The new URI is placed in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange attribute`.
If the URI has a scheme prefix, such as lb:ws://serviceid
, the lb
scheme is stripped from the URI and placed in the ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
for use later in the filter chain.
7.8. The Websocket Routing Filter --- 使用Spring Web Socket将转发 Websocket 请求
-
Websocket 路由过滤器
If the URL located in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange attribute has a ws
or wss
scheme, the websocket routing filter runs. It uses the Spring WebSocket infrastructure to forward the websocket request downstream.
You can load-balance websockets by prefixing the URI with lb
, such as lb:ws://serviceid
.
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
# SockJS route
- id: websocket_sockjs_route
uri: http://localhost:3001
predicates:
- Path=/websocket/info/**
# Normal Websocket route
- id: websocket_route
uri: ws://localhost:3001
predicates:
- Path=/websocket/**</span></span>
7.9. The Gateway Metrics Filter 监控指标
To enable gateway metrics, add spring-boot-starter-actuator as a project dependency. Then, by default, the gateway metrics filter runs as long as the property spring.cloud.gateway.metrics.enabled
is not set to false
. This filter adds a timer metric named gateway.requests
with the following tags:
-
routeId
: The route ID. -
routeUri
: The URI to which the API is routed. -
outcome
: The outcome, as classified by HttpStatus.Series. -
status
: The HTTP status of the request returned to the client. -
httpStatusCode
: The HTTP Status of the request returned to the client. -
httpMethod
: The HTTP method used for the request.
These metrics are then available to be scraped from /actuator/metrics/gateway.requests
and can be easily integrated with Prometheus to create a Grafana dashboard.
7.10. Marking An Exchange As Routed
防止重复的路由转发
After the gateway has routed a ServerWebExchange
, it marks that exchange as “routed” by adding gatewayAlreadyRouted
to the exchange attributes. Once a request has been marked as routed, other routing filters will not route the request again, essentially skipping the filter. There are convenience methods that you can use to mark an exchange as routed or check if an exchange has already been routed.
-
ServerWebExchangeUtils.isAlreadyRouted
takes aServerWebExchange
object and checks if it has been “routed”. -
ServerWebExchangeUtils.setAlreadyRouted
takes aServerWebExchange
object and marks it as “routed”.
8. HttpHeadersFilters
8.1 Forwarded Headers Filter
The Forwarded
Headers Filter creates a Forwarded
header to send to the downstream service. It adds the Host
header, scheme and port of the current request to any existing Forwarded
header.
8.2. RemoveHopByHop Headers Filter
The RemoveHopByHop
Headers Filter removes headers from forwarded requests. The default list of headers that is removed comes from the IETF.
The default removed headers are:
-
Connection
-
Keep-Alive
-
Proxy-Authenticate
-
Proxy-Authorization
-
TE
-
Trailer
-
Transfer-Encoding
-
Upgrade
To change this, set the spring.cloud.gateway.filter.remove-hop-by-hop.headers
property to the list of header names to remove.
8.3 XForwarded Headers Filter
The XForwarded
Headers Filter creates various a X-Forwarded-*
headers to send to the downstream service. It users the Host
header, scheme, port and path of the current request to create the various headers.
Creating of individual headers can be controlled by the following boolean properties (defaults to true):
-
spring.cloud.gateway.x-forwarded.for-enabled
-
spring.cloud.gateway.x-forwarded.host-enabled
-
spring.cloud.gateway.x-forwarded.port-enabled
-
spring.cloud.gateway.x-forwarded.proto-enabled
-
spring.cloud.gateway.x-forwarded.prefix-enabled
Appending multiple headers can be controlled by the following boolean properties (defaults to true):
-
spring.cloud.gateway.x-forwarded.for-append
-
spring.cloud.gateway.x-forwarded.host-append
-
spring.cloud.gateway.x-forwarded.port-append
-
spring.cloud.gateway.x-forwarded.proto-append
-
spring.cloud.gateway.x-forwarded.prefix-append
9. TLS and SSL
<span style="background-color:#f8f8f8"><span style="color:#333333">server:
ssl:
enabled: true
key-alias: scg
key-store-password: scg1234
key-store: classpath:scg-keystore.p12
key-store-type: PKCS12</span></span>
设置信任路由证书
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true</span></span>
Using an insecure trust manager is not suitable for production. For a production deployment, you can configure the gateway with a set of known certificates that it can trust with the following configuration:
设置证书
Example 65. application.yml
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#221199">spring</span><span style="color:#555555">:</span>
<span style="color:#221199"> cloud</span><span style="color:#555555">:</span>
<span style="color:#221199"> gateway</span><span style="color:#555555">:</span>
<span style="color:#221199"> httpclient</span><span style="color:#555555">:</span>
<span style="color:#221199"> ssl</span><span style="color:#555555">:</span>
<span style="color:#221199"> trustedX509Certificates</span><span style="color:#555555">:</span>
<span style="color:#555555"> - </span>cert1.pem
<span style="color:#555555"> - </span>cert2.pem</span></span>
如果Spring Cloud Gateway没有提供受信任的证书,则使用默认的信任存储(您可以通过设置javax.net.ssl.trustStore系统属性来覆盖它)。
9.1. TLS Handshake
TLS 相关设置
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
httpclient:
ssl:
handshake-timeout-millis: 10000
close-notify-flush-timeout-millis: 3000
close-notify-read-timeout-millis: 0</span></span>
10. Configuration 配置
11. Route Metadata Configuration
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
routes:
- id: route_with_metadata
uri: https://example.org
metadata:
optionName: "OptionValue"
compositeObject:
name: "value"
iAmNumber: 1</span></span>
You could acquire all metadata properties from an exchange, as follows:
<span style="background-color:#f8f8f8"><span style="color:#333333">Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get all metadata properties
route.getMetadata();
// get a single metadata property
route.getMetadata(someKey);</span></span>
12. Http Timeouts configration 超时
12.1 Global timeouts
To configure Global http timeouts: connect-timeout
must be specified in milliseconds. response-timeout
must be specified as a java.time.Duration
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s</span></span>
12.2 Pre-route timeouts
To configure per-route timeouts: connect-timeout
must be specified in milliseconds. response-timeout
must be specified in milliseconds.
<span style="background-color:#f8f8f8"><span style="color:#333333"> - id: per_route_timeouts
uri: https://example.org
predicates:
- name: Path
args:
pattern: /delay/{timeout}
metadata:
response-timeout: 200
connect-timeout: 200</span></span>
per-route timeouts configuration using Java DSL
<span style="background-color:#f8f8f8"><span style="color:#333333">import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR;
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR;
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeBuilder){
return routeBuilder.routes()
.route("test1", r -> {
return r.host("*.somehost.org").and().path("/somepath")
.filters(f -> f.addRequestHeader("header1", "header-value-1"))
.uri("http://someuri")
.metadata(RESPONSE_TIMEOUT_ATTR, 200)
.metadata(CONNECT_TIMEOUT_ATTR, 200);
})
.build();
}</span></span>
12.3. Fluent Java Routes API
<span style="background-color:#f8f8f8"><span style="color:#333333">@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {
return builder.routes()
.route(r -> r.host("**.abc.org").and().path("/image/png")
.filters(f ->
f.addResponseHeader("X-TestHeader", "foobar"))
.uri("http://httpbin.org:80")
)
.route(r -> r.path("/image/webp")
.filters(f ->
f.addResponseHeader("X-AnotherHeader", "baz"))
.uri("http://httpbin.org:80")
.metadata("key", "value")
)
.route(r -> r.order(-1)
.host("**.throttle.org").and().path("/get")
.filters(f -> f.filter(throttle.apply(1,
1,
10,
TimeUnit.SECONDS)))
.uri("http://httpbin.org:80")
.metadata("key", "value")
)
.build();
}</span></span>
This style also allows for more custom predicate assertions. The predicates defined by RouteDefinitionLocator
beans are combined using logical and
. By using the fluent Java API, you can use the and()
, or()
, and negate()
operators on the Predicate
class.
12.4. The DiscoveryClient Route Definition Locator
You can configure the gateway to create routes based on services registered with a DiscoveryClient
compatible service registry.
To enable this, set spring.cloud.gateway.discovery.locator.enabled=true
and make sure a DiscoveryClient
implementation (such as Netflix Eureka, Consul, or Zookeeper) is on the classpath and enabled.
使用服务注册中心 ,文档没说清楚,查询别的博客,说是配置后,id默认为服务名称
测试id故意写错,uri正常服务写法,可以正常访问
12.4.1 Configuring Predicates and Filters For DiscoveryClient
Routes
The default predicate is a path predicate defined with the pattern /serviceId/**
, where serviceId
is the ID of the service from the DiscoveryClient
.
默认使用服务id配置路径
The default filter is a rewrite path filter with the regex /serviceId/(?<remaining>.*)
and the replacement /${remaining}
. This strips the service ID from the path before the request is sent downstream.
默认过滤器会重写路径,过滤掉服务id
If you want to customize the predicates or filters used by the DiscoveryClient
routes, set spring.cloud.gateway.discovery.locator.predicates[x]
and spring.cloud.gateway.discovery.locator.filters[y]
. When doing so, you need to make sure to include the default predicate and filter shown earlier, if you want to retain that functionality. The following example shows what this looks like:
Example 71. application.properties
<span style="background-color:#f8f8f8"><span style="color:#333333">spring.cloud.gateway.discovery.locator.predicates[0].name: Path
spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"
spring.cloud.gateway.discovery.locator.predicates[1].name: Host
spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"
spring.cloud.gateway.discovery.locator.filters[0].name: Hystrix
spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId
spring.cloud.gateway.discovery.locator.filters[1].name: RewritePath
spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/(?<remaining>.*)'"
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"</span></span>
13. Reactor Netty Access Logs
To enable Reactor Netty access logs, set -Dreactor.netty.http.server.accessLogEnabled=true
.
配置netty log参数
Example 72. logback.xml
<span style="background-color:#f8f8f8"><span style="color:#333333"> <appender name="accessLog" class="ch.qos.logback.core.FileAppender">
<file>access_log.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<appender name="async" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="accessLog" />
</appender>
<logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
<appender-ref ref="async"/>
</logger></span></span>
14.CORS Configuration 跨域
<span style="background-color:#f8f8f8"><span style="color:#333333">spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "https://docs.spring.io"
allowedMethods:
- GET</span></span>
To provide the same CORS configuration to requests that are not handled by some gateway route predicate, set the spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping
property to true
. This is useful when you try to support CORS preflight requests and your route predicate does not evalute to true
because the HTTP method is options
.
15. Actuator API-----执行器
The /gateway
actuator endpoint lets you monitor and interact with a Spring Cloud Gateway application. To be remotely accessible, the endpoint has to be enabled and exposed over HTTP or JMX in the application properties. The following listing shows how to do so:
/gateway执行器端点允许您监视Spring云网关应用程序并与之交互。要实现远程访问,必须在应用程序属性中通过HTTP或JMX启用并公开端点。下面的清单展示了如何做到这一点:
<span style="background-color:#f8f8f8"><span style="color:#333333">management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway</span></span>
启动监控接口,需配置以上参数,还需添加依赖(请求404,找了半天,才发现是缺依赖,文档太坑了)
<span style="background-color:#f8f8f8"><span style="color:#333333"><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency></span></span>
15.1 Verbose Actuator Format 详细格式
Verbose:详细的
A new, more verbose format has been added to Spring Cloud Gateway. It adds more detail to each route, letting you view the predicates and filters associated with each route along with any configuration that is available. The following example configures /actuator/gateway/routes
:
Spring Cloud Gateway中添加了一种新的、更详细的格式。它为每个路由添加了更多的细节,允许您查看与每个路由关联的谓词和过滤器以及可用的任何配置。配置/致动器/gateway/routes的示例如下:
<span style="background-color:#f8f8f8"><span style="color:#333333">[
{
"predicate": "(Hosts: [**.addrequestheader.org] && Paths: [/headers], match trailing slash: true)",
"route_id": "add_request_header_test",
"filters": [
"[[AddResponseHeader X-Response-Default-Foo = 'Default-Bar'], order = 1]",
"[[AddRequestHeader X-Request-Foo = 'Bar'], order = 1]",
"[[PrefixPath prefix = '/httpbin'], order = 2]"
],
"uri": "lb://testservice",
"order": 0
}
]</span></span>
This feature is enabled by default. To disable it, set the following property:
Example 75. application.properties
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#0000ff">spring.cloud.gateway.actuator.verbose.enabled</span>=<span style="color:#009900">false</span></span></span>
动态配置路由使用
动态配置路由博客:https://lidong1665.blog.csdn.net/article/details/100933635
15.2. Retrieving Route Filters
This section details how to retrieve route filters, including:
15.2.1 Global Filters
To retrieve the global filters applied to all routes, make a GET
request to /actuator/gateway/globalfilters
. The resulting response is similar to the following:
<span style="background-color:#f8f8f8"><span style="color:#333333">{
"org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@77856cc5": 10100,
"org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@4f6fd101": 10000,
"org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@32d22650": -1,
"org.springframework.cloud.gateway.filter.ForwardRoutingFilter@106459d9": 2147483647,
"org.springframework.cloud.gateway.filter.NettyRoutingFilter@1fbd5e0": 2147483647,
"org.springframework.cloud.gateway.filter.ForwardPathFilter@33a71d23": 0,
"org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@135064ea": 2147483637,
"org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c05889": 2147483646
}</span></span>
15.2.2 Route Filter
To retrieve the GatewayFilter
factories applied to routes, make a GET
request to /actuator/gateway/routefilters
. The resulting response is similar to the following:
<span style="background-color:#f8f8f8"><span style="color:#333333">{
"[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null,
"[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null
}</span></span>
The response contains the details of the GatewayFilter
factories applied to any particular route. For each factory there is a string representation of the corresponding object (for example, [SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]
). Note that the null
value is due to an incomplete implementation of the endpoint controller, because it tries to set the order of the object in the filter chain, which does not apply to a GatewayFilter
factory object.
15.3. Refreshing the Route Cache
To clear the routes cache, make a POST
request to /actuator/gateway/refresh
. The request returns a 200 without a response body.
post请求,返回空实体
15.4. Retrieving the Routes Defined in the Gateway
To retrieve the routes defined in the gateway, make a GET
request to /actuator/gateway/routes
. The resulting response is similar to the following:
检索路由
GET /actuator/gateway/routes
<span style="background-color:#f8f8f8"><span style="color:#333333">[{
"route_id": "first_route",
"route_object": {
"predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@1e9d7e7d",
"filters": [
"OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory$$Lambda$436/674480275@6631ef72, order=0}"
]
},
"order": 0
},
{
"route_id": "second_route",
"route_object": {
"predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@cd8d298",
"filters": []
},
"order": 0
}]</span></span>
The response contains the details of all the routes defined in the gateway. The following table describes the structure of each element (each is a route) of the response:
Path | Type | Description |
---|---|---|
route_id | String | The route ID. |
route_object.predicate | Object | The route predicate. |
route_object.filters | Array | The GatewayFilter factories applied to the route. |
order | Number | The route order. |
15.5. Retreving Information about a Particular Route--检索特定的路由信息
To retrieve information about a single route, make a GET
request to /actuator/gateway/routes/{id}
(for example, /actuator/gateway/routes/first_route
). The resulting response is similar to the following:
GET /actuator/gateway/routes/first_route
<span style="background-color:#f8f8f8"><span style="color:#333333">{
"id": "first_route",
"predicates": [{
"name": "Path",
"args": {"_genkey_0":"/first"}
}],
"filters": [],
"uri": "https://www.uri-destination.org",
"order": 0
}]</span></span>
The following table describes the structure of the response:
Path | Type | Description |
---|---|---|
id | String | The route ID. |
predicates | Array | The collection of route predicates. Each item defines the name and the arguments of a given predicate. |
filters | Array | The collection of filters applied to the route. |
uri | String | The destination URI of the route. |
order | Number | The route order. |
15.6. Creating and Deleting a Particular Route---创建和删除一个特定的路由
To create a route, make a POST
request to /gateway/routes/{id_route_to_create}
with a JSON body that specifies the fields of the route (see Retrieving Information about a Particular Route).
To delete a route, make a DELETE
request to /gateway/routes/{id_route_to_delete}
.
15.7. Recap: The List of All endpoints ----概述:所有端点的列表 (所有api)
The folloiwng table below summarizes the Spring Cloud Gateway actuator endpoints (note that each endpoint has /actuator/gateway
as the base-path):
ID | HTTP Method | Description |
---|---|---|
globalfilters | GET | Displays the list of global filters applied to the routes. |
routefilters | GET | Displays the list of GatewayFilter factories applied to a particular route. |
refresh | POST | Clears the routes cache. |
routes | GET | Displays the list of routes defined in the gateway. |
routes/{id} | GET | Displays information about a particular route. |
routes/{id} | POST | Adds a new route to the gateway. |
routes/{id} | DELETE | Removes an existing route from the gateway. |
16. Troublesshooting 常见问题
16.1 Log Levels 日志级别
he following loggers may contain valuable troubleshooting information at the DEBUG
and TRACE
levels:
-
org.springframework.cloud.gateway
-
org.springframework.http.server.reactive
-
org.springframework.web.reactive
-
org.springframework.boot.autoconfigure.web
-
reactor.netty
-
redisratelimiter
16.2. Wiretap 监听
The Reactor Netty HttpClient
and HttpServer
can have wiretap enabled. When combined with setting the reactor.netty
log level to DEBUG
or TRACE
, it enables the logging of information, such as headers and bodies sent and received across the wire. To enable wiretap, set spring.cloud.gateway.httpserver.wiretap=true
or spring.cloud.gateway.httpclient.wiretap=true
for the HttpServer
and HttpClient
, respectively.
翻译:反应器Netty ' HttpClient '和' HttpServer '可以启用窃听。当结合将' reactor.netty '日志级别设置为' DEBUG '或' TRACE '时,它允许记录信息,如通过网络发送和接收的头部和正文。要启用监听功能,请设置“spring.cloud.gateway.httpserver”。窃听= true”或“spring.cloud.gateway.httpclient。wiretap=true ',分别为' HttpServer '和' HttpClient '。
17.Developer Guide--开发者指南
自定义组件指南
17.1. Writing Custeom Route Predicate Factories --- 编写自定义断言
In order to write a Route Predicate you will need to implement RoutePredicateFactory
. There is an abstract class called AbstractRoutePredicateFactory
which you can extend.
<span style="background-color:#f8f8f8"><span style="color:#333333">public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {
public MyRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
// grab configuration from Config object
return exchange -> {
//grab the request
ServerHttpRequest request = exchange.getRequest();
//take information from the request to see if it
//matches configuration.
return matches(config, request);
};
}
public static class Config {
//Put the configuration properties for your filter here
}
}</span></span>
17.2. Writing Custom GatewayFilter Factories ---编写自定义网关过滤
To write a GatewayFilter
, you must implement GatewayFilterFactory
. You can extend an abstract class called AbstractGatewayFilterFactory
. The following examples show how to do so:
Example 76. PreGatewayFilterFactory.java
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">PreGatewayFilterFactory</span> <span style="color:#770088">extends</span> <span style="color:#000000">AbstractGatewayFilterFactory</span><span style="color:#981a1a"><</span><span style="color:#000000">PreGatewayFilterFactory</span>.<span style="color:#000000">Config</span><span style="color:#981a1a">></span> {
<span style="color:#770088">public</span> <span style="color:#000000">PreGatewayFilterFactory</span>() {
<span style="color:#770088">super</span>(<span style="color:#000000">Config</span>.<span style="color:#770088">class</span>);
}
<span style="color:#555555">@Override</span>
<span style="color:#770088">public</span> <span style="color:#000000">GatewayFilter</span> <span style="color:#000000">apply</span>(<span style="color:#000000">Config</span> <span style="color:#000000">config</span>) {
<span style="color:#aa5500">// grab configuration from Config object</span>
<span style="color:#770088">return</span> (<span style="color:#000000">exchange</span>, <span style="color:#000000">chain</span>) <span style="color:#981a1a">-></span> {
<span style="color:#aa5500">//If you want to build a "pre" filter you need to manipulate the</span>
<span style="color:#aa5500">//request before calling chain.filter</span>
<span style="color:#000000">ServerHttpRequest</span>.<span style="color:#000000">Builder</span> <span style="color:#000000">builder</span> <span style="color:#981a1a">=</span> <span style="color:#000000">exchange</span>.<span style="color:#000000">getRequest</span>().<span style="color:#000000">mutate</span>();
<span style="color:#aa5500">//use builder to manipulate the request</span>
<span style="color:#770088">return</span> <span style="color:#000000">chain</span>.<span style="color:#000000">filter</span>(<span style="color:#000000">exchange</span>.<span style="color:#000000">mutate</span>().<span style="color:#000000">request</span>(<span style="color:#000000">builder</span>.<span style="color:#000000">build</span>()).<span style="color:#000000">build</span>());
};
}
<span style="color:#770088">public</span> <span style="color:#770088">static</span> <span style="color:#770088">class</span> <span style="color:#0000ff">Config</span> {
<span style="color:#aa5500">//Put the configuration properties for your filter here</span>
}
}</span></span>
PostGatewayFilterFactory.java
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">PostGatewayFilterFactory</span> <span style="color:#770088">extends</span> <span style="color:#000000">AbstractGatewayFilterFactory</span><span style="color:#981a1a"><</span><span style="color:#000000">PostGatewayFilterFactory</span>.<span style="color:#000000">Config</span><span style="color:#981a1a">></span> {
<span style="color:#770088">public</span> <span style="color:#000000">PostGatewayFilterFactory</span>() {
<span style="color:#770088">super</span>(<span style="color:#000000">Config</span>.<span style="color:#770088">class</span>);
}
<span style="color:#555555">@Override</span>
<span style="color:#770088">public</span> <span style="color:#000000">GatewayFilter</span> <span style="color:#000000">apply</span>(<span style="color:#000000">Config</span> <span style="color:#000000">config</span>) {
<span style="color:#aa5500">// grab configuration from Config object</span>
<span style="color:#770088">return</span> (<span style="color:#000000">exchange</span>, <span style="color:#000000">chain</span>) <span style="color:#981a1a">-></span> {
<span style="color:#770088">return</span> <span style="color:#000000">chain</span>.<span style="color:#000000">filter</span>(<span style="color:#000000">exchange</span>).<span style="color:#000000">then</span>(<span style="color:#000000">Mono</span>.<span style="color:#000000">fromRunnable</span>(() <span style="color:#981a1a">-></span> {
<span style="color:#000000">ServerHttpResponse</span> <span style="color:#000000">response</span> <span style="color:#981a1a">=</span> <span style="color:#000000">exchange</span>.<span style="color:#000000">getResponse</span>();
<span style="color:#aa5500">//Manipulate the response in some way</span>
}));
};
}
<span style="color:#770088">public</span> <span style="color:#770088">static</span> <span style="color:#770088">class</span> <span style="color:#0000ff">Config</span> {
<span style="color:#aa5500">//Put the configuration properties for your filter here</span>
}
}
</span></span>
17.2.1. Naming Custom Filters And References In Configuration
在配置中命名自定义过滤器和引用
Custom filters class names should end in GatewayFilterFactory
.
自定义过滤器类名应该以 GatewayFilterFactory 结尾
For example, to reference a filter named Something
in configuration files, the filter must be in a class named SomethingGatewayFilterFactory
.
例如,要在配置文件中引用一个名为' Something '的过滤器,该过滤器必须在一个名为' SomethingGatewayFilterFactory '的类中。
It is possible to create a gateway filter named without the
GatewayFilterFactorysuffix, such as
class AnotherThing. This filter could be referenced as
AnotherThingin configuration files. This is **not** a supported naming convention and this syntax may be removed in future releases. Please update the filter name to be compliant.
17.3 Writing Custom Global Filters 编写自定义全局过滤器
To write a custom global filter, you must implement GlobalFilter
interface. This applies the filter to all requests.
The following examples show how to set up global pre and post filters, respectively:
<span style="background-color:#f8f8f8"><span style="color:#333333">@Bean
public GlobalFilter customGlobalFilter() {
return (exchange, chain) -> exchange.getPrincipal()
.map(Principal::getName)
.defaultIfEmpty("Default User")
.map(userName -> {
//adds header to proxied request
exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();
return exchange;
})
.flatMap(chain::filter);
}
@Bean
public GlobalFilter customGlobalPostFilter() {
return (exchange, chain) -> chain.filter(exchange)
.then(Mono.just(exchange))
.map(serverWebExchange -> {
//adds header to response
serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
return serverWebExchange;
})
.then();
}</span></span>
18. Building a Simple Gateway by Using Spring MVC or Webflux
The following describes an alternative style gateway. None of the prior documentation applies to what follows. | |
---|---|
Spring Cloud Gateway provides a utility object called ProxyExchange
. You can use it inside a regular Spring web handler as a method parameter. It supports basic downstream HTTP exchanges through methods that mirror the HTTP verbs. With MVC, it also supports forwarding to a local handler through the forward()
method. To use the ProxyExchange
, include the right module in your classpath (either spring-cloud-gateway-mvc
or spring-cloud-gateway-webflux
).
The following MVC example proxies a request to /test
downstream to a remote server:
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#555555">@RestController</span>
<span style="color:#555555">@SpringBootApplication</span>
<span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">GatewaySampleApplication</span> {
<span style="color:#555555">@Value</span>(<span style="color:#aa1111">"${remote.home}"</span>)
<span style="color:#770088">private</span> <span style="color:#000000">URI</span> <span style="color:#000000">home</span>;
<span style="color:#555555">@GetMapping</span>(<span style="color:#aa1111">"/test"</span>)
<span style="color:#770088">public</span> <span style="color:#000000">ResponseEntity</span><span style="color:#981a1a"><?></span> <span style="color:#000000">proxy</span>(<span style="color:#000000">ProxyExchange</span><span style="color:#981a1a"><</span><span style="color:#008855">byte</span>[]<span style="color:#981a1a">></span> <span style="color:#000000">proxy</span>) <span style="color:#770088">throws</span> <span style="color:#000000">Exception</span> {
<span style="color:#770088">return</span> <span style="color:#000000">proxy</span>.<span style="color:#000000">uri</span>(<span style="color:#000000">home</span>.<span style="color:#000000">toString</span>() <span style="color:#981a1a">+</span> <span style="color:#aa1111">"/image/png"</span>).<span style="color:#000000">get</span>();
}
}</span></span>
The following example does the same thing with Webflux:
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#555555">@RestController</span>
<span style="color:#555555">@SpringBootApplication</span>
<span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">GatewaySampleApplication</span> {
<span style="color:#555555">@Value</span>(<span style="color:#aa1111">"${remote.home}"</span>)
<span style="color:#770088">private</span> <span style="color:#000000">URI</span> <span style="color:#000000">home</span>;
<span style="color:#555555">@GetMapping</span>(<span style="color:#aa1111">"/test"</span>)
<span style="color:#770088">public</span> <span style="color:#000000">Mono</span><span style="color:#981a1a"><</span><span style="color:#000000">ResponseEntity</span><span style="color:#981a1a"><?>></span> <span style="color:#000000">proxy</span>(<span style="color:#000000">ProxyExchange</span><span style="color:#981a1a"><</span><span style="color:#008855">byte</span>[]<span style="color:#981a1a">></span> <span style="color:#000000">proxy</span>) <span style="color:#770088">throws</span> <span style="color:#000000">Exception</span> {
<span style="color:#770088">return</span> <span style="color:#000000">proxy</span>.<span style="color:#000000">uri</span>(<span style="color:#000000">home</span>.<span style="color:#000000">toString</span>() <span style="color:#981a1a">+</span> <span style="color:#aa1111">"/image/png"</span>).<span style="color:#000000">get</span>();
}
}</span></span>
Convenience methods on the ProxyExchange
enable the handler method to discover and enhance the URI path of the incoming request. For example, you might want to extract the trailing elements of a path to pass them downstream:
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#555555">@GetMapping</span>(<span style="color:#aa1111">"/proxy/path/**"</span>)
<span style="color:#770088">public</span> <span style="color:#000000">ResponseEntity</span><span style="color:#981a1a"><?></span> <span style="color:#0000ff">proxyPath</span>(<span style="color:#000000">ProxyExchange</span><span style="color:#981a1a"><</span><span style="color:#008855">byte</span>[]<span style="color:#981a1a">></span> <span style="color:#000000">proxy</span>) <span style="color:#770088">throws</span> <span style="color:#000000">Exception</span> {
<span style="color:#008855">String</span> <span style="color:#000000">path</span> <span style="color:#981a1a">=</span> <span style="color:#000000">proxy</span>.<span style="color:#000000">path</span>(<span style="color:#aa1111">"/proxy/path/"</span>);
<span style="color:#770088">return</span> <span style="color:#000000">proxy</span>.<span style="color:#000000">uri</span>(<span style="color:#000000">home</span>.<span style="color:#000000">toString</span>() <span style="color:#981a1a">+</span> <span style="color:#aa1111">"/foos/"</span> <span style="color:#981a1a">+</span> <span style="color:#000000">path</span>).<span style="color:#000000">get</span>();
}</span></span>
All the features of Spring MVC and Webflux are available to gateway handler methods. As a result, you can inject request headers and query parameters, for instance, and you can constrain the incoming requests with declarations in the mapping annotation. See the documentation for @RequestMapping
in Spring MVC for more details of those features.
You can add headers to the downstream response by using the header()
methods on ProxyExchange
.
You can also manipulate response headers (and anything else you like in the response) by adding a mapper to the get()
method (and other methods). The mapper is a Function
that takes the incoming ResponseEntity
and converts it to an outgoing one.
First-class support is provided for “sensitive” headers (by default, cookie
and authorization
), which are not passed downstream, and for “proxy” (x-forwarded-*
) headers.
19. Configuration properties
Appendix A: Common application properties
Various properties can be specified inside your application.properties
file, inside your application.yml
file, or as command line switches. This appendix provides a list of common Spring Cloud Gateway properties and references to the underlying classes that consume them.
Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list. Also, you can define your own properties. | |
---|---|
更多推荐
所有评论(0)