116. Global Filters
GlobalFilter
接口具有与GatewayFilter
相同的签名。这些是特殊filter,有条件地应用于所有路由。 (此接口和用法可能会在将来的里程碑中更改)。
116.1 组合的全局filter和 GatewayFilterOrder
当请求进入(并与路由匹配)时,过滤 Web 处理程序会将GlobalFilter
的所有实例和GatewayFilter
的所有特定于路由的实例添加到filter链中。该组合的filter链通过org.springframework.core.Ordered
接口排序,可以通过实现getOrder()
方法或使用@Order
Comments 来设置。
由于 Spring Cloud Gateway 区分filter逻辑执行的“前”和“后”阶段(请参阅:工作原理),因此优先级最高的filter将在“前”阶段中处于第一个阶段,而在“后”阶段中处于最后一个阶段“-相。
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 转发路由filter
ForwardRoutingFilter
在交换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
中查找 URI。如果该网址具有forward
方案(即forward:///localendpoint
),它将使用 Spring DispatcherHandler
来处理请求。请求 URL 的路径部分将被转发 URL 中的路径覆盖。未经修改的原始 url 会附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性中的列表中。
116.3 LoadBalancerClient filter
LoadBalancerClientFilter
在交换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
中查找 URI。如果该 URL 具有lb
方案(即lb://myservice
),它将使用 Spring Cloud LoadBalancerClient
将名称(在上一个示例中为myservice
)解析为实际的主机和端口,并在同一属性中替换 URI。未经修改的原始 URL 会附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性中的列表中。filter还将查看ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
属性,以查看其是否等于lb
,然后应用相同的规则。
application.yml.
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
Note
默认情况下,当在LoadBalancer
中找不到服务实例时,将返回503
。您可以通过设置spring.cloud.gateway.loadbalancer.use404=true
来配置网关以返回404
。
Note
从LoadBalancer
返回的ServiceInstance
的isSecure
值将覆盖对网关的请求中指定的方案。例如,如果请求通过HTTPS
进入网关,但ServiceInstance
表示它不安全,则下游请求将通过HTTP
发出。相反的情况也可以适用。但是,如果在网关配置中为路由指定了GATEWAY_SCHEME_PREFIX_ATTR
,则前缀将被删除,并且从路由 URL 生成的方案将覆盖ServiceInstance
配置。
116.4 净值路由filter
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
交换属性中的 URL 具有http
或https
方案,则将运行 Netty 路由filter。它使用 Netty HttpClient
发出下游代理请求。响应将放在ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
交换属性中,以供以后的filter使用。 (有一个实验性的WebClientHttpRoutingFilter
执行相同的功能,但不需要净值)
116.5 Netty 写响应filter
如果ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
交换属性中有 Netty HttpClientResponse
,则NettyWriteResponseFilter
运行。它在所有其他filter完成后运行,并将代理响应写回到网关 Client 端响应。 (有一个实验性的WebClientWriteResponseFilter
执行相同的功能,但不需要净值)
116.6 RouteToRequestUrl filter
如果ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR
交换属性中有Route
对象,则RouteToRequestUrlFilter
运行。它基于请求 URI 创建一个新 URI,但使用Route
对象的 URI 属性对其进行了更新。新的 URI 放在ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange 属性中。
如果 URI 具有方案前缀(例如lb:ws://serviceid
),则从 URI 中剥离lb
方案,并将其放在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
中,以供以后在filter链中使用。
116.7 Websocket 路由filter
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
交换属性中的 URL 具有ws
或wss
方案,则 Websocket 路由filter将运行。它使用 Spring Web Socket 基础结构向下游转发 Websocket 请求。
Websocket 可以通过在 URI 前面加上lb
(例如lb:ws://serviceid
)来实现负载均衡。
Note
如果您使用SockJS作为正常 http 的后备,则应该配置正常的 HTTP 路由以及 Websocket 路由。
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 filter
要启用网关度量标准,请添加 spring-boot-starter-actuator 作为项目依赖项。然后,默认情况下,只要属性spring.cloud.gateway.metrics.enabled
未设置为false
,网关度量filter就会运行。此filter添加一个带有以下标记的名为“ gateway.requests”的计时器度量标准:
-
routeId
:RouteID -
routeUri
:API 将被路由到的 URI -
outcome
:按HttpStatus.Series分类的结果 -
status
:Http 返回给 Client 端的请求状态
然后可以从/actuator/metrics/gateway.requests
抓取这些 Metrics,并可以将它们与 Prometheus 轻松集成以创建Grafana dashboard。
Note
要启用 pometheus 端点,请添加 micrometer-registry-prometheus 作为项目依赖项。
116.9 按路由进行交换
网关路由ServerWebExchange
之后,它将通过在交换属性中添加gatewayAlreadyRouted
将该交换标记为“已路由”。将请求标记为已路由后,其他路由filter将不会再次路由请求,实质上会跳过该filter。您可以使用多种便捷方法将交换标记为已路由,或者检查交换是否已路由。
-
ServerWebExchangeUtils.isAlreadyRouted
取得ServerWebExchange
对象并检查其是否已“路由” -
ServerWebExchangeUtils.setAlreadyRouted
取得ServerWebExchange
对象并将其标记为“已路由”