网关 Spring Cloud Gateway 内置全局过滤器


💨 作者:laker,因为喜欢LOL滴神faker,又是NBA湖人队🏀(laker)粉丝儿(主要是老詹的粉丝儿),本人又姓,故取笔名:laker
❤️喜欢分享自己工作中遇到的问题和解决方案以及一些读书笔记和心得分享
🌰本人创建了微信公众号【Java大厂面试官】,用于和大家交流分享
🏰 个人微信【lakernote】,加作者备注下暗号:cv之道


本文Spring Cloud Gateway 版本:2020.0.0

全局过滤器作用于所有的路由,不需要单独配置,我们可以用它来实现很多统一化处理的业务需求,比如权限认证、IP 访问限制等。

接口定义类 org.springframework.cloud.gateway.filter.GlobalFilter,具体代码如下所示。

public interface GlobalFilter {
  Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

此接口及其用法可能会在将来的里程碑版本中更改。

全局过滤器和网关过滤器工厂顺序

当请求与路由匹配时,过滤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;
    }
}

ForwardRoutingFilter 转发

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

LoadBalancerClientFilter 负载均衡

LoadBalancerClientFilter在交换属性查找一个URI命名ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR。如果URL的方案为lb(例如lb://myservice),它将使用Spring CloudLoadBalancerClient将名称(myservice在这种情况下)解析为实际的主机和端口,并在同一属性中替换URI。未经修改的原始URL将附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR属性中的列表。过滤器还会在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR属性中查找是否相等lb。如果是这样,则适用相同的规则。以下清单配置了一个LoadBalancerClientFilter

spring:
  cloud:
    gateway:
      routes:
      - id: myRoute
        uri: lb://service
        predicates:
        - Path=/service/**

默认情况下,如果在中找不到服务实例LoadBalancer,则返回503。您可以404通过设置将网关配置为返回spring.cloud.gateway.loadbalancer.use404=true

从覆盖返回 的isSecureServiceInstanceLoadBalancer覆盖对网关的请求中指定的方案。例如,如果请求通过进入网关,HTTPSServiceInstance指示该请求不安全,则通过发出下游请求 HTTP。相反的情况也可以适用。但是,如果GATEWAY_SCHEME_PREFIX_ATTR在“网关”配置中为路由指定了该前缀,则将删除前缀,并且来自路由URL的结果方案将覆盖该ServiceInstance配置。

网关支持所有LoadBalancer功能。您可以在Spring Cloud Commons文档中阅读有关它们的更多信息。

ReactiveLoadBalancerClientFilter 响应式负载均衡

ReactiveLoadBalancerClientFilter在交换属性查找一个URI命名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/**

默认情况下,如果在中找不到服务实例LoadBalancer,则返回503。您可以404通过设置将网关配置为返回spring.cloud.gateway.loadbalancer.use404=true

从覆盖返回 的isSecureServiceInstanceLoadBalancer覆盖对网关的请求中指定的方案。例如,如果请求通过进入网关,HTTPSServiceInstance指示该请求不安全,则通过发出下游请求 HTTP。相反的情况也可以适用。但是,如果GATEWAY_SCHEME_PREFIX_ATTR在“网关”配置中为路由指定了该前缀,则将删除前缀,并且来自路由URL的结果方案将覆盖该ServiceInstance配置。

网关支持所有LoadBalancer功能。您可以在Spring Cloud Commons文档中阅读有关它们的更多信息。

路由

如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交换属性中的URL具有httphttps方案,则将运行Netty路由筛选器。它使用NettyHttpClient发出下游代理请求。响应将放入ServerWebExchangeUtils.CLIENT_RESPONSE_ATTRexchange属性中,以供以后的过滤器使用。(也有一个实验WebClientHttpRoutingFilter,执行相同的功能,但不需要Netty。)

代理响应

NettyWriteResponseFilter,如果有一个运行的NettyHttpClientResponseServerWebExchangeUtils.CLIENT_RESPONSE_ATTR交换属性。它在所有其他筛选器完成后运行,并将代理响应写回到网关客户端响应。(也有一个实验WebClientWriteResponseFilter,执行相同的功能,但不需要Netty。)

RouteToRequestUrlFilter

如果交换属性中有一个Route对象ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR,则RouteToRequestUrlFilter运行。它基于请求URI创建一个新的URI,但使用Route对象的URI属性进行更新。新的URI放置在ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTRexchange属性中。

如果URI具有方案前缀(例如)lb:ws://serviceid,则将lb方案从URI中剥离,并放入中以ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR供稍后在过滤器链中使用。

websocket路由过滤器

如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTRexchange属性中的URL具有wswss方案,则将运行websocket路由筛选器。它使用Spring WebSocket基础结构向下游转发websocket请求。

你可以用前缀的URI负载平衡的WebSockets 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/**

网关指标过滤器

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

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

然后可以从这些指标中删除这些指标,/actuator/metrics/gateway.requests并可以将它们轻松地与Prometheus集成以创建Grafana 仪表板

要启用Prometheus端点,请添加micrometer-registry-prometheus为项目依赖项。

将交换标记为已路由

网关对a进行路由之后ServerWebExchange,通过添加gatewayAlreadyRouted 交换属性将交换标记为“已路由” 。将请求标记为已路由后,其他路由筛选器将不会再次路由请求,实质上会跳过该筛选器。您可以使用多种便利的方法将交换标记为已路由或检查交换是否已路由。

  • ServerWebExchangeUtils.isAlreadyRouted接收一个ServerWebExchange对象并检查它是否已被“路由”。
  • ServerWebExchangeUtils.setAlreadyRouted接收一个ServerWebExchange对象并将其标记为“已路由”。

Spring Cloud 相关系列文章目录

网关服务

Spring Cloud Gateway


QQ群【837324215】
关注我的公众号【Java大厂面试官】,回复:常用工具资源等关键词(更多关键词,关注后注意提示信息)获取更多免费资料。

公众号也会持续输出高质量文章,和大家共同进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lakernote

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值