7. 全局过滤器
这GlobalFilter
interface 的签名与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
在 exchange 属性中查找 URIServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
.
如果 URL 具有forward
方案(例如forward:///localendpoint
),它使用 SpringDispatcherHandler
以处理请求。
请求 URL 的 path 部分被转发 URL 中的路径覆盖。
未修改的原始 URL 将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
属性。
7.3. 使用ReactiveLoadBalancerClientFilter
这ReactiveLoadBalancerClientFilter
在 exchange 属性中查找名为ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
.
如果 URL 具有lb
方案(例如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 配置。 |
Gateway 支持所有 LoadBalancer 功能。您可以在 Spring Cloud Commons 文档中阅读有关它们的更多信息。 |
7.4. Netty 路由过滤器
如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
exchange 属性具有http
或https
方案。
它使用 NettyHttpClient
进行下游代理请求。
响应被放入ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR
exchange 属性,以便在以后的过滤器中使用。
(还有一个实验性的WebClientHttpRoutingFilter
执行相同的功能,但不需要 Netty。
7.5. Netty Write 响应过滤器
这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 具有 scheme 前缀,例如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. Gateway Metrics 过滤器
要启用网关指标,请将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. 将 Exchange 标记为 Routed
网关路由ServerWebExchange
,它会通过添加gatewayAlreadyRouted
添加到 exchange 属性中。一旦请求被标记为已路由,其他路由过滤器将不会再次路由该请求。
基本上跳过了过滤器。您可以使用一些便捷的方法将交易所标记为已路由
或者检查是否已路由 Exchange。
-
ServerWebExchangeUtils.isAlreadyRouted
采用ServerWebExchange
object 并检查它是否已被 “routed” 处理。 -
ServerWebExchangeUtils.setAlreadyRouted
采用ServerWebExchange
对象并将其标记为 “routed”。