SpringCloud Gateway使用及原理分析大全——断言及过滤器(上篇)
SpringCloud Gateway使用及原理分析大全(下篇)
GlobalFilter接口与GatewayFilter具有相同的签名。这些是有条件地应用于所有路由的特殊过滤器。
在未来的里程碑版本中,该接口及其用法可能会有所变化。
当请求与路由匹配时,筛选web处理程序会将GlobalFilter的所有实例和GatewayFilter的所有路由特定实例添加到筛选器链中。这个组合的过滤器链由org.springframework.core.Ordered接口排序,您可以通过实现getOrder()方法来设置该接口。
由于Spring Cloud Gateway区分过滤器逻辑执行的“前”和“后”阶段,优先级最高的过滤器是“前”阶段的第一个,是“后”阶段的最后一个。
// 配置一个过滤器链
@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;
}
}
ForwardRoutingFilter在exchange属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR中查找URI。
如果URL有转发方案(比如forward:///localendpoint),它使用Spring DispatcherHandler来处理请求。
请求URL的路径部分被转发URL中的路径覆盖。
未修改的原始URL被附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR中的列表。
ReactiveLoadBalancerClientFilter在名为ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR属性中查找URI。
如果URL有lb方案(比如lb://myservice),它使用Spring Cloud ReactorLoadBalancer将名称(本例中为myservice)解析为实际的主机和端口,并替换相同属性中的URI。
未修改的原始URL被附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR中的列表.
该筛选器还会在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR中查找属性,看是否等于lb。如果是这样,同样的规则也适用。
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
默认情况下,当ReactorLoadBalancer找不到服务实例时,将返回503。通过设置spring.cloud.gateway.loadbalancer.use404=true,可以将网关配置为返回404。
从ReactiveLoadBalancerClientFilter返回的ServiceInstance的isSecure值将覆盖向网关发出的请求中指定的方案。例如,如果请求通过HTTPS进入网关,但ServiceInstance指示它不安全,则下游请求通过HTTP发出。相反的情况也适用。但是,如果在网关配置中为路由指定了GATEWAY_SCHEME_PREFIX_ATTR,则前缀将被删除,并且从路由URL生成的方案将覆盖ServiceInstance配置。
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR的 exchange属性中的URL具有http或https方案,则Netty路由过滤器将运行。它使用Netty HttpClient发出下游代理请求。响应放在ServerWebExchangeUtils中。CLIENT_RESPONSE_ATTR交换属性,以便在以后的过滤器中使用。(还有一个实验性的WebClientHttpRoutingFilter,它执行相同的功能,但不需要Netty。)
如果ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR中有Netty HttpClientResponse,则NettyWriteResponseFilter将运行。它在所有其他过滤器完成后运行,并将代理响应写回网关客户端响应。(还有一个实验性的WebClientWriteResponseFilter,它执行相同的功能,但不需要Netty)
如果ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR中有路由对象,则运行RouteToRequestUrlFilter。它基于请求URI创建了一个新的URI,但是用路由对象的URI属性进行了更新。新的URI放在ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR中。
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange属性中的URL具有ws或wss方案,websocket路由过滤器将运行。它使用Spring WebSocket基础设施向下游转发WebSocket请求。
可以通过在URI前面加上lb来对websockets进行负载平衡,比如lb:ws://serviceid。
如果使用SockJS作为普通HTTP的后备,那么应该配置一个普通HTTP路由以及websocket路由。
# 配置一个websocket 路由过滤器
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/**
要启用网关指标,请添加spring-boot-starter-actuator作为项目依赖项。然后,默认情况下,只要属性spring.cloud.gateway.metrics.enabled未设置为false,网关度量过滤器就会运行。该过滤器添加一个名为spring.cloud.gateway.requests的计时器指标,带有以下标记:
此外,通过属性spring.cloud.gateway.metrics.tags.path.enabled(默认情况下,设置为false),您可以使用标记激活额外的指标:
这些指标可以从/actuator/metrics/spring.cloud.gateway.requests中获取,并可以轻松地与Prometheus集成以创建Grafana仪表板。
要启用prometheus端点,请添加micrometer-registry-prometheus作为项目依赖项。
在网关路由了ServerWebExchange之后,它通过将gatewayAlreadyRouted添加到Exchange属性来将该exchange标记为“routed”。一旦请求被标记为已路由,其他路由过滤器将不会再次路由该请求,实质上跳过了该过滤器。有一些方便的方法可以用来将交换标记为已路由,或者检查交换是否已经被路由。
HttpHeadersFilters在将请求发送到下游之前应用于请求,例如在NettyRoutingFilter中。
转发头过滤器创建一个转发头发送到下游服务。它将当前请求的主机请求头、方案和端口添加到任何现有的转发请求头中。
RemoveHopByHop头筛选器从转发的请求中删除头。被删除的默认头列表来自IETF。
默认删除的请求头有:
要更改这一点,请将spring.cloud.gateway.filter.remove-hop-by-hop.headers属性设置为要删除的请求头名称列表。
XForwarded Headers筛选器创建各种X-Forwarded-*标头以发送到下游服务。它使用当前请求的主机头、方案、端口和路径来创建各种头。
单个标题的创建可由以下布尔属性控制(默认为true):
追加多个标题可以由以下布尔属性控制(默认为true):
网关可以通过遵循通常的Spring服务器配置来监听HTTPS上的请求。
server:
ssl:
enabled: true
key-alias: scg
key-store-password: scg1234
key-store: classpath:scg-keystore.p12
key-store-type: PKCS12
可以将网关路由路由到HTTP和HTTPS后端。如果要路由到HTTPS后端,可以使用以下配置将网关配置为信任所有下游证书:
spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true
使用不安全的信任管理器不适合生产。对于生产部署,可以使用一组它可以信任的已知证书来配置网关,配置如下:
spring:
cloud:
gateway:
httpclient:
ssl:
trustedX509Certificates:
- cert1.pem
- cert2.pem
如果Spring Cloud Gateway没有提供可信证书,则使用默认的信任存储(可以通过设置javax.net.ssl.trustStore系统属性来覆盖它)。
网关维护一个客户端池,用于路由到后端。当通过HTTPS通信时,客户端发起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的配置由RouteDefinitionLocator实例的集合驱动。
// RouteDefinitionLocator接口的定义
public interface RouteDefinitionLocator {
Flux<RouteDefinition> getRouteDefinitions();
}
默认情况下,propertiesroutededefinitionlocator使用Spring Boot的@ConfigurationProperties机制加载属性。
早期的配置示例都使用一种快捷表示法,它使用位置参数而不是命名参数。以下两个示例是等效的:
spring:
cloud:
gateway:
routes:
- id: setstatus_route
uri: https://example.org
filters:
- name: SetStatus
args:
status: 401
- id: setstatusshortcut_route
uri: https://example.org
filters:
- SetStatus=401
对于网关的某些用途,属性是足够的,但是某些生产用例从外部源(如数据库)加载配置中受益。未来的milestone版本将会有基于Spring数据仓库的RouteDefinitionLocator实现,比如Redis、MongoDB和Cassandra。
要启用RouteDefinition指标,请添加spring-boot-starter-actuator作为项目依赖项。然后,默认情况下,只要属性spring.cloud.gateway.metrics.enabled设置为true,指标就可用。将添加一个名为spring.cloud.gateway.routes.count的测量指标,其值为RouteDefinitions的数量。该指标可从/actuator/metrics/spring.cloud.gateway.routes.count获得。
# 可以使用元数据为每个路径配置附加参数
spring:
cloud:
gateway:
routes:
- id: route_with_metadata
uri: https://example.org
metadata:
optionName: "OptionValue"
compositeObject:
name: "value"
iAmNumber: 1
// 可以从exchange中获取所有元数据属性
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get all metadata properties
route.getMetadata();
// get a single metadata property
route.getMetadata(someKey);
可以为所有路由配置Http超时(响应和连接),并为每个特定路由覆盖。
要配置全局http超时:
# 配置全局超时
spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s
要配置每路由超时:
# 为每个路由设置超时
- id: per_route_timeouts
uri: https://example.org
predicates:
- name: Path
args:
pattern: /delay/{timeout}
metadata:
response-timeout: 200
connect-timeout: 200
// 使用java为每个路由设置超时
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();
}
# 注意:当单个路由设置response-timeout为负值时,将会禁用全局的response-timeout。
- id: per_route_timeouts
uri: https://example.org
predicates:
- name: Path
args:
pattern: /delay/{timeout}
metadata:
response-timeout: -1
为了在Java中实现简单的配置,RouteLocatorBuilder bean包含了一个流畅的API。
// 静态引入 GatewayFilters 和RoutePredicates
@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();
}
这种风格还允许更多的自定义断言。RouteDefinitionLocator beans定义的断言使用逻辑and进行组合,通过使用 Java API,您可以在谓词类上使用and()、or()和negate()运算符。
可以将网关配置为基于向DiscoveryClient兼容服务注册表注册的服务来创建路由。
要实现这一点,请设置spring.cloud.gateway.discovery.locator.enabled=true,并确保DiscoveryClient实现(如Netflix Eureka, Consul, or Zookeeper)位于类路径中并已启用。
默认情况下,网关为使用DiscoveryClient创建的路由定义了一个断言和过滤器。
默认断言是用模式/serviceId/**定义的路径断言,其中serviceId是来自DiscoveryClient的服务的Id。
默认过滤器是一个重写路径过滤器,其正则为 /serviceId/?(?
如果想定制DiscoveryClient路由使用的断言或过滤器, 设置 spring.cloud.gateway.discovery.locator.predicates[x] 和spring.cloud.gateway.discovery.locator.filters[y],这样做的时候,如果想保留这个功能,需要确保包含前面显示的默认断言和过滤器,比如:
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: CircuitBreaker
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}'"
设置-Dreactor.netty.http.server.accessLogEnabled=true 打开Reactor Netty访问日志。
(它必须是Java系统属性,而不是Spring Boot属性。)
可以将日志记录系统配置为具有单独的访问日志文件。以下示例创建了一个回退配置:
<appender name="accessLog" class="ch.qos.logback.core.FileAppender">
<file>access_log.logfile>
<encoder>
<pattern>%msg%npattern>
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>
可以配置网关来控制CORS行为。“全局”CORS配置是URL模式到Spring Framework CORS configuration的映射。
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "https://docs.spring.io"
allowedMethods:
- GET
在上面的示例中,对于所有GET requested路径,来自docs.spring.io的请求都允许CORS请求。
为了向不由某些网关路由断言处理的请求提供相同的CORS配置,请将spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping设置为true。当尝试支持CORS预检请求,并且由于HTTP方法为options,路由断言未设置为true时,这很有用。
/gateway actuator端点允许监控Spring Cloud Gateway应用程序并与之交互。要进行远程访问,必须在应用程序属性中启用并通过HTTP或JMX公开端点。
# 启用端点
management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway
Spring Cloud Gateway增加了一种新的更详细的格式。它为每条路由添加了更多的细节,可以查看与每条路由相关联的谓词和过滤器,以及任何可用的配置。
// 配置/actuator/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
}
]
# 默认情况下,此功能处于启用状态。要禁用它,请设置以下属性:(在未来的版本中,这将默认为true。)
spring.cloud.gateway.actuator.verbose.enabled=false
要检索应用于所有路由的全局过滤器,请向/actuator/gateway/global filters发出GET请求。产生的响应类似于以下内容:
{
"org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@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
}
该响应包含已安装的全局过滤器的详细信息。对于每个全局过滤器,都有一个过滤器对象的字符串表示形式(例如,org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5)和过滤器链中相应的顺序。
要检索应用于路由的GatewayFilter工厂,请向/actuator/gateway/routefilters发出GET请求。产生的响应类似于以下内容:
{
"[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null,
"[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null
}
响应包含应用于任何特定路由的GatewayFilter工厂的详细信息。对于每个工厂,都有一个相应对象的字符串表示(例如,[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object])。请注意,空值是由于端点控制器的不完整实现造成的,因为它试图设置筛选器链中对象的顺序,这不适用于GatewayFilter工厂对象。
要清除路由缓存,请向/actuator/gateway/refresh发出POST请求。该请求返回一个没有响应正文的200。
要检索网关中定义的路由,请向/actuator/gateway/routes发出GET请求。产生的响应类似于以下内容:
[{
"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
}]
响应包含网关中定义的所有路由的详细信息。下表描述了响应的每个元素(每个元素都是一个路由)的结构:
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. |
要检索有关单个路由的信息,请向/actuator/gateway/routes/{id}发出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
}
下表描述了响应的结构:
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. |
要创建路由,请向/gateway/routes/{id_route_to_create}发出POST请求,并在JSON正文中指定路由的字段(请参见5、检索特定路由的信息)。
要删除路由,请向/gateway/routes/{id_route_to_delete}发出删除请求。
下表总结了Spring Cloud Gateway actuator端点(注意每个端点都有/actuator/gateway作为基本路径):
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. |
Spring Cloud Gateway提供了两个RouteDefinitionRepository实现。
第一个是inmemorroutedefinitionrepository,它只存在于一个网关实例的内存中。这种类型的存储库不适合跨多个网关实例填充路由。
为了在Spring Cloud Gateway实例集群之间共享路由,可以使用RedisRouteDefinitionRepository。要启用这种类型的存储库,spring.cloud.gateway.redis-route-definition-repository.enabled必须设置为true,与RedisRateLimiter Filter Factory 类似,它需要使用spring-boot-starter-data-redis-reactive starter。
下列记录器可能包含有价值的DEBUG 和TRACE级别故障排除信息:
Reactor Netty HttpClient和HttpServer可以启用窃听。当与将reactor.netty日志级别设置为DEBUG或TRACE结合使用时,它可以记录信息,例如通过网络发送和接收的头和主体。要启用窃听,请分别为httpserver和httpclient设置spring.cloud.gateway.httpserver.wiretap=true 和 spring.cloud.gateway.httpclient.wiretap=true。
为了编写路由断言,需要将RoutePredicateFactory实现为一个bean。有一个名为AbstractRoutePredicateFactory的抽象类,可以对其进行扩展。
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.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
}
}
要编写GatewayFilter,必须将GatewayFilterFactory实现为bean。可以扩展名为AbstractGatewayFilterFactory的抽象类。
@Component
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
}
}
@Component
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
}
}
自定义筛选器类名应以GatewayFilterFactory结尾。
例如,要在配置文件中引用名为Something的筛选器,该筛选器必须位于名为SomethingGatewayFilterFactory的类中。
可以创建不带GatewayFilterFactory后缀的网关筛选器,如class AnotherThing。这个过滤器可以作为配置文件中的另一个东西被引用。这不是受支持的命名约定,在未来的版本中可能会删除此语法。请更新过滤器名称以符合要求。
要编写自定义全局过滤器,必须将GlobalFilter 接口实现为bean。这会将过滤器应用于所有请求。
// 设置全局的前置过滤器和后置过滤器
@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();
}
Spring Cloud Gateway提供了一个名为ProxyExchange的实用程序对象。可以在常规的Spring web处理程序中使用它作为方法参数。它通过镜像HTTP动词的方法支持基本的下游HTTP交换。对于MVC,它还支持通过forward()方法转发到本地处理程序。要使用ProxyExchange,请在类路径中包含正确的模块(spring-cloud-gateway-mvc或spring-cloud-gateway-webflux)。
// 以下MVC示例将请求代理到/测试下游的远程服务器:
@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();
}
}
//下面的例子对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();
}
}
// ProxyExchange上的便利方法使处理程序方法能够发现和增强传入请求的URI路径。例如,您可能希望提取路径的尾部元素,以便将它们传递到下游:
@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();
}
Spring MVC和Webflux的所有特性都可以用于网关处理程序方法。因此,例如,可以注入请求头和查询参数,并且可以用映射注释中的声明来约束传入的请求。
可以使用ProxyExchange上的header()方法向下游响应添加标头。
还可以通过向get()方法(以及其他方法)添加映射器来操作响应头(以及响应中您喜欢的任何内容)。映射器是一个函数,它获取传入的响应实体并将其转换为传出的响应实体。
为“敏感”头(默认为cookie和authorization)和“代理”(x-forwarded-*)头提供了一流的支持,前者不传递给下游。
查看所有Spring Cloud Gateway相关配置属性的列表(可以在application.properties文件内、application.yml文件内或作为命令行开关指定各种属性。下面提供了常见Spring Cloud Gateway属性的列表,以及对使用这些属性的底层类的引用。)(属性贡献可以来自类路径上的其他jar文件,因此这不是一个详尽的列表。此外,还可以定义自己的属性。)
Name | Default | Description |
---|---|---|
spring.cloud.gateway.default-filters | List of filter definitions that are applied to every route. | |
spring.cloud.gateway.discovery.locator.enabled | FALSE | Flag that enables DiscoveryClient gateway integration. |
spring.cloud.gateway.discovery.locator.filters | ||
spring.cloud.gateway.discovery.locator.include-expression | TRUE | SpEL expression that will evaluate whether to include a service in gateway integration or not, defaults to: true. |
spring.cloud.gateway.discovery.locator.lower-case-service-id | FALSE | Option to lower case serviceId in predicates and filters, defaults to false. Useful with eureka when it automatically uppercases serviceId. so MYSERIVCE, would match /myservice/** |
spring.cloud.gateway.discovery.locator.predicates | ||
spring.cloud.gateway.discovery.locator.route-id-prefix | The prefix for the routeId, defaults to discoveryClient.getClass().getSimpleName() + “_”. Service Id will be appended to create the routeId. | |
spring.cloud.gateway.discovery.locator.url-expression | ‘lb://’+serviceId | SpEL expression that create the uri for each route, defaults to: ‘lb://’+serviceId. |
spring.cloud.gateway.enabled | TRUE | Enables gateway functionality. |
spring.cloud.gateway.fail-on-route-definition-error | TRUE | Option to fail on route definition errors, defaults to true. Otherwise, a warning is logged. |
spring.cloud.gateway.filter.add-request-header.enabled | TRUE | Enables the add-request-header filter. |
spring.cloud.gateway.filter.add-request-parameter.enabled | TRUE | Enables the add-request-parameter filter. |
spring.cloud.gateway.filter.add-response-header.enabled | TRUE | Enables the add-response-header filter. |
spring.cloud.gateway.filter.circuit-breaker.enabled | TRUE | Enables the circuit-breaker filter. |
spring.cloud.gateway.filter.dedupe-response-header.enabled | TRUE | Enables the dedupe-response-header filter. |
spring.cloud.gateway.filter.fallback-headers.enabled | TRUE | Enables the fallback-headers filter. |
spring.cloud.gateway.filter.hystrix.enabled | TRUE | Enables the hystrix filter. |
spring.cloud.gateway.filter.json-to-grpc.enabled | TRUE | Enables the JSON to gRPC filter. |
spring.cloud.gateway.filter.map-request-header.enabled | TRUE | Enables the map-request-header filter. |
spring.cloud.gateway.filter.modify-request-body.enabled | TRUE | Enables the modify-request-body filter. |
spring.cloud.gateway.filter.modify-response-body.enabled | TRUE | Enables the modify-response-body filter. |
spring.cloud.gateway.filter.prefix-path.enabled | TRUE | Enables the prefix-path filter. |
spring.cloud.gateway.filter.preserve-host-header.enabled | TRUE | Enables the preserve-host-header filter. |
spring.cloud.gateway.filter.redirect-to.enabled | TRUE | Enables the redirect-to filter. |
spring.cloud.gateway.filter.remove-hop-by-hop.headers | ||
spring.cloud.gateway.filter.remove-hop-by-hop.order | 0 | |
spring.cloud.gateway.filter.remove-request-header.enabled | TRUE | Enables the remove-request-header filter. |
spring.cloud.gateway.filter.remove-request-parameter.enabled | TRUE | Enables the remove-request-parameter filter. |
spring.cloud.gateway.filter.remove-response-header.enabled | TRUE | Enables the remove-response-header filter. |
spring.cloud.gateway.filter.request-header-size.enabled | TRUE | Enables the request-header-size filter. |
spring.cloud.gateway.filter.request-header-to-request-uri.enabled | TRUE | Enables the request-header-to-request-uri filter. |
spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key | TRUE | Switch to deny requests if the Key Resolver returns an empty key, defaults to true. |
spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code | HttpStatus to return when denyEmptyKey is true, defaults to FORBIDDEN. | |
spring.cloud.gateway.filter.request-rate-limiter.enabled | TRUE | Enables the request-rate-limiter filter. |
spring.cloud.gateway.filter.request-size.enabled | TRUE | Enables the request-size filter. |
spring.cloud.gateway.filter.retry.enabled | TRUE | Enables the retry filter. |
spring.cloud.gateway.filter.rewrite-location-response-header.enabled | TRUE | Enables the rewrite-location-response-header filter. |
spring.cloud.gateway.filter.rewrite-location.enabled | TRUE | Enables the rewrite-location filter. |
spring.cloud.gateway.filter.rewrite-path.enabled | TRUE | Enables the rewrite-path filter. |
spring.cloud.gateway.filter.rewrite-response-header.enabled | TRUE | Enables the rewrite-response-header filter. |
spring.cloud.gateway.filter.save-session.enabled | TRUE | Enables the save-session filter. |
spring.cloud.gateway.filter.secure-headers.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’ | |
spring.cloud.gateway.filter.secure-headers.content-type-options | nosniff | |
spring.cloud.gateway.filter.secure-headers.disable | ||
spring.cloud.gateway.filter.secure-headers.download-options | noopen | |
spring.cloud.gateway.filter.secure-headers.enabled | TRUE | Enables the secure-headers filter. |
spring.cloud.gateway.filter.secure-headers.frame-options | DENY | |
spring.cloud.gateway.filter.secure-headers.permitted-cross-domain-policies | none | |
spring.cloud.gateway.filter.secure-headers.referrer-policy | no-referrer | |
spring.cloud.gateway.filter.secure-headers.strict-transport-security | max-age=631138519 | |
spring.cloud.gateway.filter.secure-headers.xss-protection-header | 1 ; mode=block | |
spring.cloud.gateway.filter.set-path.enabled | TRUE | Enables the set-path filter. |
spring.cloud.gateway.filter.set-request-header.enabled | TRUE | Enables the set-request-header filter. |
spring.cloud.gateway.filter.set-request-host-header.enabled | TRUE | Enables the set-request-host-header filter. |
spring.cloud.gateway.filter.set-response-header.enabled | TRUE | Enables the set-response-header filter. |
spring.cloud.gateway.filter.set-status.enabled | TRUE | Enables the set-status filter. |
spring.cloud.gateway.filter.strip-prefix.enabled | TRUE | Enables the strip-prefix filter. |
spring.cloud.gateway.forwarded.enabled | TRUE | Enables the ForwardedHeadersFilter. |
spring.cloud.gateway.global-filter.adapt-cached-body.enabled | TRUE | Enables the adapt-cached-body global filter. |
spring.cloud.gateway.global-filter.forward-path.enabled | TRUE | Enables the forward-path global filter. |
spring.cloud.gateway.global-filter.forward-routing.enabled | TRUE | Enables the forward-routing global filter. |
spring.cloud.gateway.global-filter.load-balancer-client.enabled | TRUE | Enables the load-balancer-client global filter. |
spring.cloud.gateway.global-filter.netty-routing.enabled | TRUE | Enables the netty-routing global filter. |
spring.cloud.gateway.global-filter.netty-write-response.enabled | TRUE | Enables the netty-write-response global filter. |
spring.cloud.gateway.global-filter.reactive-load-balancer-client.enabled | TRUE | Enables the reactive-load-balancer-client global filter. |
spring.cloud.gateway.global-filter.remove-cached-body.enabled | TRUE | Enables the remove-cached-body global filter. |
spring.cloud.gateway.global-filter.route-to-request-url.enabled | TRUE | Enables the route-to-request-url global filter. |
spring.cloud.gateway.global-filter.websocket-routing.enabled | TRUE | Enables the websocket-routing global filter. |
spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping | FALSE | If global CORS config should be added to the URL handler. |
spring.cloud.gateway.globalcors.cors-configurations | ||
spring.cloud.gateway.handler-mapping.order | 1 | The order of RoutePredicateHandlerMapping. |
spring.cloud.gateway.httpclient.compression | FALSE | Enables compression for Netty HttpClient. |
spring.cloud.gateway.httpclient.connect-timeout | The connect timeout in millis, the default is 45s. | |
spring.cloud.gateway.httpclient.max-header-size | The max response header size. | |
spring.cloud.gateway.httpclient.max-initial-line-length | The max initial line length. | |
spring.cloud.gateway.httpclient.pool.acquire-timeout | Only for type FIXED, the maximum time in millis to wait for acquiring. | |
spring.cloud.gateway.httpclient.pool.eviction-interval | 0 | Perform regular eviction checks in the background at a specified interval. Disabled by default ({@link Duration#ZERO}) |
spring.cloud.gateway.httpclient.pool.max-connections | Only for type FIXED, the maximum number of connections before starting pending acquisition on existing ones. | |
spring.cloud.gateway.httpclient.pool.max-idle-time | Time in millis after which the channel will be closed. If NULL, there is no max idle time. | |
spring.cloud.gateway.httpclient.pool.max-life-time | Duration after which the channel will be closed. If NULL, there is no max life time. | |
spring.cloud.gateway.httpclient.pool.metrics | FALSE | Enables channel pools metrics to be collected and registered in Micrometer. Disabled by default. |
spring.cloud.gateway.httpclient.pool.name | proxy | The channel pool map name, defaults to proxy. |
spring.cloud.gateway.httpclient.pool.type | Type of pool for HttpClient to use, defaults to ELASTIC. | |
spring.cloud.gateway.httpclient.proxy.host | Hostname for proxy configuration of Netty HttpClient. | |
spring.cloud.gateway.httpclient.proxy.non-proxy-hosts-pattern | Regular expression (Java) for a configured list of hosts. that should be reached directly, bypassing the proxy | |
spring.cloud.gateway.httpclient.proxy.password | Password for proxy configuration of Netty HttpClient. | |
spring.cloud.gateway.httpclient.proxy.port | Port for proxy configuration of Netty HttpClient. | |
spring.cloud.gateway.httpclient.proxy.type | proxyType for proxy configuration of Netty HttpClient. | |
spring.cloud.gateway.httpclient.proxy.username | Username for proxy configuration of Netty HttpClient. | |
spring.cloud.gateway.httpclient.response-timeout | The response timeout. | |
spring.cloud.gateway.httpclient.ssl.close-notify-flush-timeout | 3000ms | SSL close_notify flush timeout. Default to 3000 ms. |
spring.cloud.gateway.httpclient.ssl.close-notify-read-timeout | 0 | SSL close_notify read timeout. Default to 0 ms. |
spring.cloud.gateway.httpclient.ssl.default-configuration-type | The default ssl configuration type. Defaults to TCP. | |
spring.cloud.gateway.httpclient.ssl.handshake-timeout | 10000ms | SSL handshake timeout. Default to 10000 ms |
spring.cloud.gateway.httpclient.ssl.key-password | Key password, default is same as keyStorePassword. | |
spring.cloud.gateway.httpclient.ssl.key-store | Keystore path for Netty HttpClient. | |
spring.cloud.gateway.httpclient.ssl.key-store-password | Keystore password. | |
spring.cloud.gateway.httpclient.ssl.key-store-provider | Keystore provider for Netty HttpClient, optional field. | |
spring.cloud.gateway.httpclient.ssl.key-store-type | JKS | Keystore type for Netty HttpClient, default is JKS. |
spring.cloud.gateway.httpclient.ssl.trusted-x509-certificates | Trusted certificates for verifying the remote endpoint’s certificate. | |
spring.cloud.gateway.httpclient.ssl.use-insecure-trust-manager | FALSE | Installs the netty InsecureTrustManagerFactory. This is insecure and not suitable for production. |
spring.cloud.gateway.httpclient.websocket.max-frame-payload-length | Max frame payload length. | |
spring.cloud.gateway.httpclient.websocket.proxy-ping | TRUE | Proxy ping frames to downstream services, defaults to true. |
spring.cloud.gateway.httpclient.wiretap | FALSE | Enables wiretap debugging for Netty HttpClient. |
spring.cloud.gateway.httpserver.wiretap | FALSE | Enables wiretap debugging for Netty HttpServer. |
spring.cloud.gateway.loadbalancer.use404 | FALSE | |
spring.cloud.gateway.metrics.enabled | FALSE | Enables the collection of metrics data. |
spring.cloud.gateway.metrics.prefix | spring.cloud.gateway | The prefix of all metrics emitted by gateway. |
spring.cloud.gateway.metrics.tags | Tags map that added to metrics. | |
spring.cloud.gateway.predicate.after.enabled | TRUE | Enables the after predicate. |
spring.cloud.gateway.predicate.before.enabled | TRUE | Enables the before predicate. |
spring.cloud.gateway.predicate.between.enabled | TRUE | Enables the between predicate. |
spring.cloud.gateway.predicate.cloud-foundry-route-service.enabled | TRUE | Enables the cloud-foundry-route-service predicate. |
spring.cloud.gateway.predicate.cookie.enabled | TRUE | Enables the cookie predicate. |
spring.cloud.gateway.predicate.header.enabled | TRUE | Enables the header predicate. |
spring.cloud.gateway.predicate.host.enabled | TRUE | Enables the host predicate. |
spring.cloud.gateway.predicate.method.enabled | TRUE | Enables the method predicate. |
spring.cloud.gateway.predicate.path.enabled | TRUE | Enables the path predicate. |
spring.cloud.gateway.predicate.query.enabled | TRUE | Enables the query predicate. |
spring.cloud.gateway.predicate.read-body.enabled | TRUE | Enables the read-body predicate. |
spring.cloud.gateway.predicate.remote-addr.enabled | TRUE | Enables the remote-addr predicate. |
spring.cloud.gateway.predicate.weight.enabled | TRUE | Enables the weight predicate. |
spring.cloud.gateway.predicate.xforwarded-remote-addr.enabled | TRUE | Enables the xforwarded-remote-addr predicate. |
spring.cloud.gateway.redis-rate-limiter.burst-capacity-header | X-RateLimit-Burst-Capacity | The name of the header that returns the burst capacity configuration. |
spring.cloud.gateway.redis-rate-limiter.config | ||
spring.cloud.gateway.redis-rate-limiter.include-headers | TRUE | Whether or not to include headers containing rate limiter information, defaults to true. |
spring.cloud.gateway.redis-rate-limiter.remaining-header | X-RateLimit-Remaining | The name of the header that returns number of remaining requests during the current second. |
spring.cloud.gateway.redis-rate-limiter.replenish-rate-header | X-RateLimit-Replenish-Rate | The name of the header that returns the replenish rate configuration. |
spring.cloud.gateway.redis-rate-limiter.requested-tokens-header | X-RateLimit-Requested-Tokens | The name of the header that returns the requested tokens configuration. |
spring.cloud.gateway.restrictive-property-accessor.enabled | TRUE | Restricts method and property access in SpEL. |
spring.cloud.gateway.routes | List of Routes. | |
spring.cloud.gateway.set-status.original-status-header-name | The name of the header which contains http code of the proxied request. | |
spring.cloud.gateway.streaming-media-types | ||
spring.cloud.gateway.x-forwarded.enabled | TRUE | If the XForwardedHeadersFilter is enabled. |
spring.cloud.gateway.x-forwarded.for-append | TRUE | If appending X-Forwarded-For as a list is enabled. |
spring.cloud.gateway.x-forwarded.for-enabled | TRUE | If X-Forwarded-For is enabled. |
spring.cloud.gateway.x-forwarded.host-append | TRUE | If appending X-Forwarded-Host as a list is enabled. |
spring.cloud.gateway.x-forwarded.host-enabled | TRUE | If X-Forwarded-Host is enabled. |
spring.cloud.gateway.x-forwarded.order | 0 | The order of the XForwardedHeadersFilter. |
spring.cloud.gateway.x-forwarded.port-append | TRUE | If appending X-Forwarded-Port as a list is enabled. |
spring.cloud.gateway.x-forwarded.port-enabled | TRUE | If X-Forwarded-Port is enabled. |
spring.cloud.gateway.x-forwarded.prefix-append | TRUE | If appending X-Forwarded-Prefix as a list is enabled. |
spring.cloud.gateway.x-forwarded.prefix-enabled | TRUE | If X-Forwarded-Prefix is enabled. |
spring.cloud.gateway.x-forwarded.proto-append | TRUE | If appending X-Forwarded-Proto as a list is enabled. |
spring.cloud.gateway.x-forwarded.proto-enabled | TRUE | If X-Forwarded-Proto is enabled. |
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter