116. Global Filters
GlobalFilter
接口与GatewayFilter
具有相同的签名。这些是特殊的过滤器,有条件地应用于所有 routes。 (此界面和用法可能会在未来的里程碑中发生变化)。
116.1 组合了 Global Filter 和 GatewayFilter Ordering
当请求进入(并匹配 Route)时,Filtering Web Handler 会将GlobalFilter
的所有实例和GatewayFilter
的所有 route 特定实例添加到过滤器链中。这个组合的过滤器链按org.springframework.core.Ordered
接口排序,可以通过实现getOrder()
方法或使用@Order
annotation 来设置。
由于 Spring Cloud Gateway 区分过滤器逻辑执行的“前”和“后”阶段(参见:工作原理),优先级最高的过滤器将是“pre”-phase 中的第一个和“post”中的最后一个-phase。
ExampleConfiguration.java.
@Bean
@Order(-1)
public GlobalFilter a() {
return (exchange, chain) -> {
log.info("first pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("third post filter");
}));
};
}
@Bean
@Order(0)
public GlobalFilter b() {
return (exchange, chain) -> {
log.info("second pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("second post filter");
}));
};
}
@Bean
@Order(1)
public GlobalFilter c() {
return (exchange, chain) -> {
log.info("third pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("first post filter");
}));
};
}
116.2 前向路由过滤器
ForwardRoutingFilter
在交换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
中查找 URI。如果 url 有一个forward
scheme(即forward:///localendpoint
),它将使用 Spring DispatcherHandler
来处理请求。请求 URL 的路径部分将被转发 URL 中的路径覆盖。未修改的原始 URL 将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性的列表中。
116.3 LoadBalancerClient 过滤器
LoadBalancerClientFilter
在交换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
中查找 URI。如果 url 有一个lb
scheme(即lb://myservice
),它将使用 Spring Cloud LoadBalancerClient
将 name(前一个 example 中的myservice
)解析为实际的 host 和 port,并替换相同属性中的 URI。未修改的原始 URL 将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性的列表中。过滤器还将查看ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
属性以查看它是否等于lb
然后应用相同的规则。
application.yml.
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
116.4 Netty 路由过滤器
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange 属性中的 url 具有http
或https
scheme,则运行 Netty 路由过滤器。它使用 Netty HttpClient
来发出下游代理请求。响应放在ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
exchange 属性中,以便在以后的过滤器中使用。 (有一个实验WebClientHttpRoutingFilter
执行相同的功能,但不需要 netty)
116.5 Netty 写入响应过滤器
如果ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
exchange 属性中存在 Netty HttpClientResponse
,则运行NettyWriteResponseFilter
。在完成所有其他过滤器之后 run,并将代理响应写回网关客户端响应。 (有一个实验WebClientWriteResponseFilter
执行相同的 function,但不需要 netty)
116.6 RouteToRequestUrl 过滤器
如果ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR
exchange 属性中有Route
object,则运行RouteToRequestUrlFilter
。它根据请求 URI 创建一个新 URI,但使用Route
object 的 URI 属性进行更新。新 URI 放在ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange 属性`中。
如果 URI 具有 scheme 前缀(例如lb:ws://serviceid
),则lb
scheme 将从 URI 中剥离并放置在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
中,以便稍后在过滤器链中使用。
116.7 Websocket 路由过滤器
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange 属性中的 url 具有ws
或wss
scheme,则运行 Websocket 路由过滤器。它使用 Spring Web Socket 基础结构将 Websocket 请求转发到下游。
Websockets 可以通过为lb
加前缀来为 load-balanced,例如lb:ws://serviceid
。
如果您使用SockJS作为普通 http 的后备,则应配置普通的 HTTP route 以及 Websocket Route。
application.yml.
spring:
cloud:
gateway:
routes:
# SockJS route
- id: websocket_sockjs_route
uri: http://localhost:3001
predicates:
- Path=/websocket/info/**
# Normwal Websocket route
- id: websocket_route
uri: ws://localhost:3001
predicates:
- Path=/websocket/**
116.8 网关 Metrics 过滤器
要启用 Gateway Metrics,请将 spring-boot-starter-actuator 添加为项目依赖项。然后,默认情况下,网关 Metrics 筛选器运行为 long,因为 property spring.cloud.gateway.metrics.enabled
未设置为false
。此过滤器添加名为“gateway.requests”的计时器度量标准,其中包含以下标记:
-
routeId
:route id -
routeUri
:API 将路由到的 URI -
outcome
:按HttpStatus.Series分类的结果 -
status
:请求的 Http 状态返回给 client
然后可以从/actuator/metrics/gateway.requests
中删除这些 metrics,并且可以轻松地与 Prometheus 集成以创建Grafana 仪表板。
要启用 pometheus 端点,请将 micrometer-registry-prometheus 添加为项目依赖项。
116.9 使交换路由
在网关路由ServerWebExchange
之后,它会通过将gatewayAlreadyRouted
添加到交换机属性来将该交换标记为“路由”。一旦请求被标记为路由,其他路由过滤器将不会再次路由请求,实质上是跳过过滤器。您可以使用便捷方法将交换标记为路由,或检查交换是否已路由。
-
ServerWebExchangeUtils.isAlreadyRouted
需要ServerWebExchange
object 并检查它是否已“路由” -
ServerWebExchangeUtils.setAlreadyRouted
采用ServerWebExchange
object 并将其标记为“路由”