SpringCloud gateway全局过滤器

GlobalFilter接口具有与GatewayFilter相同的签名。这些是有条件地应用于所有路由的特殊过滤器。

组合GlobalFilter和GatewayFilter

当请求与路由匹配时,过滤web处理程序会将GlobalFilter的所有实例和GatewayFilter的所有路由特定实例添加到过滤器链中。这个组合的过滤器链由org.springframework.core.Ordered接口排序。由于Spring Cloud Gateway区分了过滤器逻辑执行的“前”和“后”阶段,因此优先级最高的过滤器是“前”阶段的第一个执行,也是“后”相位的最后一个执行。

@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("custom global filter");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

要自定义全局过滤器,实现GlobalFilter并交给Spring管理即可。

1、Forward Routing Filter

ForwardRoutingFilter在交换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR中查找URI。如果URL具有转发方案(例如forward:///localendpoint),它使用Spring DispatcherHandler来处理该请求。请求URL的路径部分被转发URL中的路径覆盖。未修改的原始URL将附加到ServerWebExchangeUtils.GATEWAY_original_REQUEST_URL_ATTR属性中的列表中。

2、ReactiveLoadBalancerClientFilter

ReactiveLoadBalancerClientFilter在名为ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR的交换属性中查找URI。如果URL具有lb方案(如lb://myservice),它将使用Spring Cloud ReactorLoadBalancer将名称解析为实际主机和端口,并替换同一属性中的URI。未修改的原始URL将附加到ServerWebExchangeUtils.GATEWAY_original_REQUEST_URL_ATTR属性中的列表中。该筛选器还会在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR属性中查找它是否等于lb。如果是,则适用相同的规则。

3、 Netty Routing Filter

如果ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交换属性中的URL具有http或https方案,则运行Netty路由过滤器。它使用Netty HttpClient来进行下游代理请求。响应被放入ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR交换属性中,以便在以后的过滤器中使用。

4、Netty Write Response Filter

如果ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR交换属性中存在Netty HttpClientResponse,则运行NettyWriteResponseFilter。它在所有其他过滤器完成后运行,并将代理响应写回网关客户端响应。

5、RouteToRequestUrl Filter

如果ServerWebExchangeUtils.GATEWAY_Route_ATTR交换属性中有Route对象,则会运行RouteToRequestUrlFilter。它根据请求URI创建一个新的URI,但使用Route对象的URI属性进行更新。新的URI位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交换属性中。如果URI具有方案前缀,例如lb:ws://serviceid,则会从URI中剥离lb方案,并将其放置在ServerWebExchangeUtils.GATEWAY_scheme_prefix_ATTR中,以便稍后在过滤器链中使用。

6、Websocket Routing Filter

如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交换属性中的URL具有ws或wss方案,则会运行websocket路由筛选器。它使用Spring WebSocket基础结构将WebSocket请求转发到下游。可以通过在URI前面加lb来实现websocket的负载平衡,例如lb:ws://serviceid。

7、Gateway Metrics Filter

要启用网关指标,请添加spring-boot-starter-actuator作为项目依赖项。然后,默认情况下,只要属性spring.cloud.gateway.metrics.enabled未设置为false,网关度量过滤器就会运行。此筛选器添加一个名为spring.cloud.gateway.requests的计时器度量,该度量具有以下标记:

  • routeId:路由ID。
  • routeUri:API路由到的URI。
  • output:结果,按HttpStatus.Series分类。
  • status:返回到客户端的请求的HTTP状态。
  • httpStatusCode:返回到客户端的请求的HTTP状态。
  • httpMethod:用于请求的HTTP方法。

此外,通过属性spring.cloud.gateway.metrics.tags.path.enabled(默认情况下,设置为false),可以使用标记激活额外的度量:

  • path:请求的路径。

然后,可以从/executor/metrics/spring.cloud.gateway.requests中抓取这些指标,并可以轻松地与Prometheus集成以创建Grafana仪表板。

 

GatewayServer模块添加依赖:

     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

在application.yml配置:

management:
  endpoints:
   web:
    exposure:
     include: '*'


spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/{segment}
          filters:
              - StripPrefix=1
      metrics:
        tags:
          path:
            enabled: true
        enabled: true

management.endpoints.web.exposure.include开启actuator端点。访问http://localhost:8500/actuator/metrics/spring.cloud.gateway.requests:

{
    "name": "spring.cloud.gateway.requests",
    "description": null,
    "baseUnit": "seconds",
    "measurements": [
        {
            "statistic": "COUNT",
            "value": 1.0
        },
        {
            "statistic": "TOTAL_TIME",
            "value": 0.175096068
        },
        {
            "statistic": "MAX",
            "value": 0.175096068
        }
    ],
    "availableTags": [
        {
            "tag": "routeUri",
            "values": [
                "lb://producer"
            ]
        },
        {
            "tag": "path",
            "values": [
                "/producer/{segment}"
            ]
        },
        {
            "tag": "path.enabled",
            "values": [
                "true"
            ]
        },
        {
            "tag": "routeId",
            "values": [
                "Goods-Server"
            ]
        },
        {
            "tag": "httpMethod",
            "values": [
                "GET"
            ]
        },
        {
            "tag": "outcome",
            "values": [
                "SUCCESSFUL"
            ]
        },
        {
            "tag": "status",
            "values": [
                "OK"
            ]
        },
        {
            "tag": "httpStatusCode",
            "values": [
                "200"
            ]
        }
    ]
}

将Exchange标记为已路由

网关路由ServerWebExchange后,通过将gatewayAlreadyRouted添加到交换属性,将该交换标记为“已路由”。一旦一个请求被标记为已路由,其他路由过滤器就不会再次路由该请求,基本上跳过了过滤器。可以使用一些方便的方法将交换标记为已路由,或检查交换是否已路由。

  • ServerWebExchangeUtils.isAlreadyRouted获取ServerWebExchange对象并检查该对象是否已“路由”。
  • ServerWebExchangeUtils.setAlreadyRouted获取ServerWebExchange对象并将其标记为“已路由”。
posted @   shigp1  阅读(589)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示