7. 全局过滤器
这GlobalFilter
接口具有与GatewayFilter
.
这些是有条件地应用于所有路由的特殊过滤器。
此接口及其用法可能会在未来的里程碑版本中发生变化。 |
7.1. 组合全局过滤器和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;
}
}
7.2. 转发路由过滤器
这ForwardRoutingFilter
在交换属性中查找 URIServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
.
如果 URL 具有forward
scheme(例如forward:///localendpoint
),它使用 SpringDispatcherHandler
来处理请求。
请求 URL 的路径部分将被转发 URL 中的路径覆盖。
未修改的原始 URL 将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性。
7.3.ReactiveLoadBalancerClientFilter
这ReactiveLoadBalancerClientFilter
在名为ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
.
如果 URL 具有lb
scheme(例如lb://myservice
),它使用 Spring CloudReactorLoadBalancer
以解析名称 (myservice
在本例中)到实际的主机和端口,并替换同一属性中的 URI。
未修改的原始 URL 将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性。
过滤器还会查看ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
属性,看看它是否等于lb
.
如果是这样,则适用相同的规则。
以下列表配置了一个ReactiveLoadBalancerClientFilter
:
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
默认情况下,当ReactorLoadBalancer 一个503 被返回。
您可以将网关配置为返回404 通过设置spring.cloud.gateway.loadbalancer.use404=true . |
这isSecure 的值ServiceInstance 从ReactiveLoadBalancerClientFilter 重写
向网关发出的请求中指定的方案。
例如,如果请求通过HTTPS 但是ServiceInstance 表示它不安全,则下游请求将HTTP .
相反的情况也可能适用。
但是,如果GATEWAY_SCHEME_PREFIX_ATTR 为网关配置中的路由指定,则前缀将被剥离,路由 URL 中生成的方案将覆盖ServiceInstance 配置。 |
网关支持所有 LoadBalancer 功能。您可以在 Spring Cloud Commons 文档中阅读有关它们的更多信息。 |
7.4. Netty 路由过滤器
Netty 路由过滤器在位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange 属性有一个http
或https
方案。
它使用 NettyHttpClient
发出下游代理请求。
响应被放在ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
exchange 属性,以便在以后的筛选器中使用。
(还有一个实验WebClientHttpRoutingFilter
执行相同的功能,但不需要 Netty。
7.5. Netty 写入响应过滤器
这NettyWriteResponseFilter
如果有 Netty,则运行HttpClientResponse
在ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
exchange 属性。
它在所有其他筛选器完成后运行,并将代理响应写回网关客户端响应。
(还有一个实验WebClientWriteResponseFilter
执行相同的功能,但不需要 Netty。
7.6.RouteToRequestUrl
Filter
如果有Route
对象ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR
exchange 属性,则RouteToRequestUrlFilter
运行。
它基于请求 URI 创建一个新的 URI,但使用Route
对象。
新 URI 放置在ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange 属性。
如果 URI 具有方案前缀,例如lb:ws://serviceid
这lb
方案从 URI 中剥离并放置在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
稍后在过滤器链中使用。
7.7. Websocket路由过滤器
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange 属性有一个ws
或wss
scheme,则运行 websocket 路由过滤器。它使用 Spring WebSocket 基础设施将 websocket 请求转发到下游。
您可以通过在 URI 前面添加lb
如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/**
7.8. 网关指标过滤器
要启用网关指标,请将 spring-boot-starter-actuator 添加为项目依赖项。然后,默认情况下,网关指标筛选器只要属性spring.cloud.gateway.metrics.enabled
未设置为false
.此筛选器添加了一个名为spring.cloud.gateway.requests
带有以下标签:
-
routeId
:路由 ID。 -
routeUri
:API 路由到的 URI。 -
outcome
:结果,按 HttpStatus.Series 分类。 -
status
:返回给客户端的请求的 HTTP 状态。 -
httpStatusCode
:返回给客户端的请求的 HTTP 状态。 -
httpMethod
:用于请求的 HTTP 方法。
此外,通过物业spring.cloud.gateway.metrics.tags.path.enabled
(默认情况下设置为 false),您可以使用标记激活额外的指标:
-
path
:请求的路径。
要启用 prometheus 端点,请添加micrometer-registry-prometheus 作为项目依赖项。 |
7.9. 将交换标记为路由
网关路由ServerWebExchange
,它通过添加gatewayAlreadyRouted
到交换属性。请求标记为已路由后,其他路由筛选器将不会再次路由该请求,
基本上跳过了过滤器。您可以使用一些方便的方法将交换标记为已路由
或检查交换是否已路由。
-
ServerWebExchangeUtils.isAlreadyRouted
需要一个ServerWebExchange
对象并检查它是否已被“路由”。 -
ServerWebExchangeUtils.setAlreadyRouted
需要一个ServerWebExchange
对象并将其标记为“路由”。