目录
Spring Cloud Gateway
1.1 简介
内置的过滤器工厂
4.1快捷配置
4.2 完全扩展的参数
5.Rote Predicate Factories 路由断言
5.1After Rote Predicate 在断言之后
5.2 Before Rote Predicate 在断言之前
5.3 Between Route 中间
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.11.1 The Redis RateLimiter
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 想改响应体
6.31. Default Filter 默认过滤
7. Global Filters 全局过滤
7.1 Combined Global Filter and GatewayFilter Ordering 组合全局过滤器和网关过滤器排序
7.2. Foward Routing Filter
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 监控指标
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
org.springframework.cloud
spring-cloud-starter-gateway
如不想启用网关,则配置
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.
配置:
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 #令牌桶总容量
这里简单将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 配置方式:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue #多个条件使用,
扩展的参数通常会有一个name,一个args ,args 通常是配置过滤器键值对
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
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]
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
跳转之后的链接为https://example.org/red/{segment}
// 获取请求参数
Map uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
## 请求参数red=gree 时才匹配,会成功转发
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
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
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")
)
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue
header 中添加参数传参
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{segment}
# 动态传参
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
#通过url 传参,相当于?red=blue
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddRequestParameter=foo, bar-{segment}
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
#返回结果header
X-Response-Red →Blue
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddResponseHeader=foo, bar-{segment}
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: 保留所有唯一值,以它们第一次出现的顺序保留
Hystrix:断路器
开启断路器功能,需添加hystrix的相关依赖
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: https://example.org
filters:
- Hystrix=myCommandName
自定义
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
@GetMapping("/fallback")
public Object fallback() {
Map result = new HashMap<>(3);
result.put("data",null);
result.put("message","request fallback!!!");
result.put("code",500);
return result;
}
也可以直接请求断路器,不影响正常跳转
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
配置熔断器时间测试该配置不行,暂时不知道原因
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
CircuitBreaker: 短路器
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} 动态参数
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint
重写路径
/red/123 => /blue/123
java 配置如下
@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();
}
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
根据返回的状态码,解除短路器
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"
@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();
}
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
executionExceptionTypeHeaderName
("Execution-Exception-Type"
)
executionExceptionMessageHeaderName
("Execution-Exception-Message"
)
rootCauseExceptionTypeHeaderName
("Root-Cause-Exception-Type"
)
rootCauseExceptionMessageHeaderName
("Root-Cause-Exception-Message"
)
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
在header添加参数,映射,fromHeaderand
toHeader
返回值:
xRequestRed:2222222,12321312 Blue:12321312
PrefixPath:前缀
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
请求hello 转发为 /mypath/hello
The PreserveHostHeader
GatewayFilter
factory has no parameters.
为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
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.
详细使用流程:
先说下令牌桶算法,就是:每秒向令牌桶放N个令牌,令牌桶的最大容积是M个,那么如果请求过来了,会从令牌桶中拿出一个令牌,令牌桶还剩M-1个。以此类推,当令牌桶的数量还剩0个的时候,就拒绝接受请求。所以这个情况可以支持突发性的请求情况。就是我一致很小量的请求,但是突然来了一大波请求,令牌桶容积决定了它能接受的最大突发情况。
- 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
引入redis
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redis-reactiveartifactId>
dependency>
@Bean
KeyResolver remoteAddrKeyResolver() {
return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostName());
}
那么使劲刷新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} |
|
---|---|
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.
要求添加依赖
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
replenishRate=1
, requestedTokens=60
and burstCapacity=60
will result in a limit of 1 request/min
.
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}" 需先定义
key-resolver: "#{@userKeyResolver}" 需先定义
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
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
状态码:
已定义范围 | 分类 | |
---|---|---|
1XX | 100-101 | 信息提示 |
2XX | 200-206 | 成功 |
3XX | 300-305 | 重定向 |
4XX | 400-415 | 客户端错误 |
5XX | 500-505 | 服务器错误 |
The RemoveRequestHeader
GatewayFilter
factory takes a name
parameter. It is the name of the header to be removed.
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo #移除header X-Request-Foo
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo #移除响应头 X-Response-Foo
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
:
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red #移除请求参数 red
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red(?/?.*), $\{segment}
重写路径
/red/blue => /blue/red
不太懂
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
参数 stripVersionMode 可选值如下:
NEVER_STRIP:版本信息不会被剥离,即使原始请求路径不包含版本 AS_IN_REQUEST:仅当原始请求路径不包含任何版本时,才会剥离版本【默认】 ALWAYS_STRIP:即使原始请求路径包含版本,也会剥离版本 参数 hostValue,如果提供,会替换 Response Header Location 值中的 host:port 部分;如果不提供,则会使用 Request 的 Host 作为默认值 参数 protocolRegex,协议会与该值匹配,如果不匹配,过滤器不回做任何操作,默认值 http|https|ftp|ftps
RewriteResponseHeader 重写原始响应中的某个Header Header名称,值的正则表达式,重写后的值
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
response.setHeader("X-Response-Red", "/42?user=ford&password=omg!what&flag=true");
保存 Session,在向下游服务转发请求之前强制执行 WebSession::save操作
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
如果将 Spring Security 与 Spring Session 集成,并希望确保安全性详细信息已转发到远程进程,那么这一点至关重要。
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
SetPath 修改原始的请求路径 修改后的路径
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
For a request path of /red/blue
, this sets the path to /blue
before making the downstream request.
有两个参数 name , value
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}
有两个参数 name ,value
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}
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
spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
When a request is made through the gateway to /name/blue/red
, the request made to nameservice
looks like nameservice/red
.
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 using org.springframework.http.HttpStatus
.
methods
: The HTTP methods that should be retried, represented by using org.springframework.http.HttpMethod
.
series
: The series of status codes to be retried, represented by using org.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 of firstBackoff * (factor ^ n)
, where n
is the iteration. If maxBackoff
is configured, the maximum backoff applied is limited to maxBackoff
. If basedOnPreviousValue
is true, the backoff is calculated byusing prevBackoff * factor
.
The following defaults are configured for Retry
filter, if enabled:
retries
: Three times
series
: 5XX series
methods
: GET method
exceptions
: IOException
and TimeoutException
backoff
: disabled
The following listing configures a Retry GatewayFilter
:
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
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
certain 某些
situation : 情况
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
The SetRequestHostHeader
GatewayFilter
factory replaces the value of the host header with example.org
. 替换host
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
:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
(exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri))
.build();
}
static class Hello {
String message;
public Hello() { }
public Hello(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
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. |
|
---|---|
@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();
}
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
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
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.
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("custom global filter");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
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.
LoadBalancerClient Filter | 整合Ribbon实现负载均衡 |
---|---|
url 使用服务代替
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
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
:
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
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. |
|
---|---|
使用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.)
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.)
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.
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
.
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/**
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.
防止重复的路由转发
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 a ServerWebExchange
object and checks if it has been “routed”.
ServerWebExchangeUtils.setAlreadyRouted
takes a ServerWebExchange
object and marks it as “routed”.
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.
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.
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
server:
ssl:
enabled: true
key-alias: scg
key-store-password: scg1234
key-store: classpath:scg-keystore.p12
key-store-type: PKCS12
设置信任路由证书
spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true
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
spring:
cloud:
gateway:
httpclient:
ssl:
trustedX509Certificates:
- cert1.pem
- cert2.pem
如果Spring Cloud Gateway没有提供受信任的证书,则使用默认的信任存储(您可以通过设置javax.net.ssl.trustStore系统属性来覆盖它)。
TLS 相关设置
spring:
cloud:
gateway:
httpclient:
ssl:
handshake-timeout-millis: 10000
close-notify-flush-timeout-millis: 3000
close-notify-read-timeout-millis: 0
spring:
cloud:
gateway:
routes:
- id: route_with_metadata
uri: https://example.org
metadata:
optionName: "OptionValue"
compositeObject:
name: "value"
iAmNumber: 1
You could acquire all metadata properties from an exchange, as follows:
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get all metadata properties
route.getMetadata();
// get a single metadata property
route.getMetadata(someKey);
To configure Global http timeouts: connect-timeout
must be specified in milliseconds. response-timeout
must be specified as a java.time.Duration
spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s
To configure per-route timeouts: connect-timeout
must be specified in milliseconds. response-timeout
must be specified in milliseconds.
- id: per_route_timeouts
uri: https://example.org
predicates:
- name: Path
args:
pattern: /delay/{timeout}
metadata:
response-timeout: 200
connect-timeout: 200
per-route timeouts configuration using Java DSL
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();
}
@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();
}
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.
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正常服务写法,可以正常访问
DiscoveryClient
RoutesThe 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/(?
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
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 + '/(?.*)'"
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"
To enable Reactor Netty access logs, set -Dreactor.netty.http.server.accessLogEnabled=true
.
配置netty log参数
Example 72. logback.xml
access_log.log
%msg%n
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "https://docs.spring.io"
allowedMethods:
- GET
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
.
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启用并公开端点。下面的清单展示了如何做到这一点:
management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway
启动监控接口,需配置以上参数,还需添加依赖(请求404,找了半天,才发现是缺依赖,文档太坑了)
org.springframework.boot
spring-boot-starter-actuator
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的示例如下:
[
{
"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
}
]
This feature is enabled by default. To disable it, set the following property:
Example 75. application.properties
spring.cloud.gateway.actuator.verbose.enabled=false
动态配置路由使用
动态配置路由博客:https://lidong1665.blog.csdn.net/article/details/100933635
This section details how to retrieve route filters, including:
Global Filters
[gateway-route-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:
{
"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
}
To retrieve the GatewayFilter
factories applied to routes, make a GET
request to /actuator/gateway/routefilters
. The resulting response is similar to the following:
{
"[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null,
"[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null
}
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.
To clear the routes cache, make a POST
request to /actuator/gateway/refresh
. The request returns a 200 without a response body.
post请求,返回空实体
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
[{
"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
}]
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. |
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
{
"id": "first_route",
"predicates": [{
"name": "Path",
"args": {"_genkey_0":"/first"}
}],
"filters": [],
"uri": "https://www.uri-destination.org",
"order": 0
}]
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. |
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}
.
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. |
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
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 '。
自定义组件指南
In order to write a Route Predicate you will need to implement RoutePredicateFactory
. There is an abstract class called AbstractRoutePredicateFactory
which you can extend.
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory {
public MyRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate 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
}
}
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
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {
public PreGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// grab configuration from Config object
return (exchange, chain) -> {
//If you want to build a "pre" filter you need to manipulate the
//request before calling chain.filter
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
//use builder to manipulate the request
return chain.filter(exchange.mutate().request(builder.build()).build());
};
}
public static class Config {
//Put the configuration properties for your filter here
}
}
PostGatewayFilterFactory.java
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {
public PostGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// grab configuration from Config object
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
//Manipulate the response in some way
}));
};
}
public static class Config {
//Put the configuration properties for your filter here
}
}
在配置中命名自定义过滤器和引用
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.
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:
@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();
}
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:
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@Value("${remote.home}")
private URI home;
@GetMapping("/test")
public ResponseEntity> proxy(ProxyExchange<byte[]> proxy) throws Exception {
return proxy.uri(home.toString() + "/image/png").get();
}
}
The following example does the same thing with Webflux:
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@Value("${remote.home}")
private URI home;
@GetMapping("/test")
public Mono<ResponseEntity>> proxy(ProxyExchange<byte[]> proxy) throws Exception {
return proxy.uri(home.toString() + "/image/png").get();
}
}
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:
@GetMapping("/proxy/path/**")
public ResponseEntity> proxyPath(ProxyExchange<byte[]> proxy) throws Exception {
String path = proxy.path("/proxy/path/");
return proxy.uri(home.toString() + "/foos/" + path).get();
}
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.
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. | |
---|---|