SpringCloud GateWay自定义过滤器之GatewayFilter和AbstractGatewayFactory

这篇具有很好参考价值的文章主要介绍了SpringCloud GateWay自定义过滤器之GatewayFilter和AbstractGatewayFactory。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、GatewayFilter

GatewayFilter 是一个简单的接口,用于定义网关过滤器的行为。一个网关过滤器就是一个实现了 GatewayFilter 接口的类,它可以执行在请求进入网关或响应离开网关时的某些操作。过滤器可以用于修改请求或响应,记录日志,添加头部信息,等等。

public interface GatewayFilter {

    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

}

一个简单的自定义网关过滤器,:

public class MyFilter implements GatewayFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        exchange.getAttributes().put("start",System.currentTimeMillis());
        return chain.filter(exchange).then(Mono.fromRunnable(new Runnable() {
            @Override
            public void run() {
                long start = exchange.getAttribute("start");
                System.out.println(exchange.getRequest().getURI() + "执行耗时:" + (System.currentTimeMillis()-start));
            }
        }));
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

配置:

@Configuration
public class MyConfig {
    /**配置自定义过滤器*/
    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes().route(r ->
                        r.path("/provider/**")//用户访问的路径
                                .uri("lb://service-provider")//路由的真实服务器ip+端口
                                .filters(new MyFilter()) // 局部过滤器
                                .id("provider_route")) // 路由id
                .build();
    }
}

二、AbstractGatewayFilterFactory

AbstractGatewayFilterFactory 是一个抽象类,用于更方便地创建网关过滤器。它处理过滤器的参数解析和创建,使得定义过滤器变得更加简单。

public class MyCustomGatewayFilterFactory extends AbstractGatewayFilterFactory<MyCustomGatewayFilterFactory.Config> {

    public MyCustomGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config, Class<Config> configClass) {
        // 在这里创建并返回过滤器实例
        return (exchange, chain) -> {
            // 过滤器逻辑
            return chain.filter(exchange);
        };
    }

    public static class Config {
        // 过滤器的配置参数
    }
}

下面是一个通过令牌桶算法实现的简单限流:

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;

@Component
public class RateLimitByIpGatewayFilterFactory extends AbstractGatewayFilterFactory<RateLimitByIpGatewayFilterFactory.Config> {

    public RateLimitByIpGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            // 获取请求的IP地址
            String ipAddress = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();

            // 使用简单的基于IP的限流逻辑,你可以根据实际需求选择其他限流算法
            // 这里使用一个简单的令牌桶算法作为示例
            if (isRateLimited(ipAddress, config.getLimit())) {
                // 如果超过限流阈值,返回错误响应
                exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
                return exchange.getResponse().setComplete();
            }

            // 如果未超过限流阈值,继续处理请求
            return chain.filter(exchange);
        };
    }

    private boolean isRateLimited(String ipAddress, int limit) {
        // 在这里实现你的限流逻辑,这里使用一个简单的令牌桶算法作为示例
        // 你可以使用库如Google Guava RateLimiter来简化实现
        // 这里只是一个简单的示例,请根据实际需求进行更复杂的实现
        // 在真实场景中,你可能需要将访问频率记录到数据库或分布式缓存中

        // 这里使用一个简单的Map模拟存储令牌桶
        Map<String, Long> tokenBucket = new ConcurrentHashMap<>();

        // 获取当前时间戳
        long now = System.currentTimeMillis();

        // 获取或初始化令牌桶
        tokenBucket.putIfAbsent(ipAddress, now);

        // 获取上次访问时间
        long lastAccessTime = tokenBucket.get(ipAddress);

        // 计算时间间隔
        long interval = now - lastAccessTime;

        // 计算令牌生成速率
        double rate = 1000.0 / limit; // 假设限制每秒请求次数

        // 计算应该生成的令牌数量
        int tokensToAdd = (int) (interval / rate);

        // 更新令牌桶中的令牌数量
        tokenBucket.put(ipAddress, now + tokensToAdd);

        // 检查令牌数量是否超过阈值
        return tokensToAdd > limit;
    }

    public static class Config {
        private int limit;

        public int getLimit() {
            return limit;
        }

        public void setLimit(int limit) {
            this.limit = limit;
        }
    }
}

配置文件配置限流阈值:

spring:
  cloud:
    gateway:
      routes:
        - id: rate_limit_route
          uri: http://example.com
          filters:
            - RateLimitByIp=1
          predicates:
            - Path=/api/**

上述配置将限制 /api/** 路径下的请求每秒只能有 1 次。请注意,RateLimitByIp 需要和 RateLimitByIpGatewayFilterFactory 的类名中的大小写一致,同时参数 1 是用来设置限流的阈值,你可以根据需要调整。 

  1. 固定容量的令牌桶: 令牌桶内有固定数量的令牌,这些令牌以固定的速率被添加到桶中。

  2. 令牌添加速率: 令牌以恒定的速率(例如每秒添加固定数量的令牌)被添加到令牌桶中。

  3. 令牌消耗: 当请求到达时,需要从令牌桶中获取一个令牌。如果令牌桶中有足够的令牌,则请求被允许处理,并消耗一个令牌;否则,请求被限流。

  4. 平滑限流: 由于令牌以恒定速率被添加,令牌桶算法可以实现平滑限流,即请求被均匀地处理,而不是突然被拒绝。

  5. 适应突发流量: 令牌桶算法对于处理突发流量也具有一定的适应性,因为即使令牌桶空了一段时间,一旦有令牌被添加,就可以处理新的请求。

  6. 容错性好: 由于令牌桶算法是基于时间的,因此对于时间敏感的应用来说,容错性较好。而且由于每个请求都需要从令牌桶中获取令牌,因此可以有效防止突发请求对系统的影响。

 

三、区别

  1. 设计用途:

  • GatewayFilter: 用于定义网关过滤器的行为,是一个简单的接口。每个过滤器的实现需要直接实现 GatewayFilter 接口中的方法。
  • AbstractGatewayFilterFactory: 是一个抽象类,旨在更方便地创建具有配置参数的网关过滤器。通过继承这个抽象类,你可以更容易地处理配置参数的解析和过滤器实例的创建。
  1. 用法:

  • GatewayFilter: 直接实现 GatewayFilter 接口,编写过滤器逻辑。这种方式适用于不需要配置参数的简单过滤器。
  • AbstractGatewayFilterFactory: 继承该抽象类,实现抽象方法 applyapply(C config, Class<C> configClass),并在其中处理配置参数并创建过滤器实例。这种方式适用于需要配置参数的过滤器。
  1. 配置参数:文章来源地址https://www.toymoban.com/news/detail-789192.html

  • GatewayFilter: 如果过滤器需要配置参数,需要通过其他方式(如构造函数、属性注入等)传递参数,因为 GatewayFilter 接口本身不提供直接的配置机制。
  • AbstractGatewayFilterFactory: 通过泛型参数 C 指定配置参数的类型,并在 apply 方法中接收配置参数。这使得配置参数的处理更为灵活,Spring Cloud Gateway 会负责将配置参数绑定到过滤器实例。

到了这里,关于SpringCloud GateWay自定义过滤器之GatewayFilter和AbstractGatewayFactory的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringCloud GateWay 在全局过滤器中注入OpenFeign网关后无法启动

    目录 一、问题 二、原因 1、修改配置 2、添加@Lazy注解在client上面  3、启动成功 当在gateway的全局过滤器GlobalFilter中注入OpenFeign接口的时候会一直卡在路由中,但是不会进一步,导致启动未成功也未报错失败 在gateway网关中不能使用openfeign同步调用 三、解决方法 在注入的Aut

    2024年01月19日
    浏览(33)
  • SpringCloud - Spring Cloud 之 Gateway网关,Route路由,Predicate 谓词/断言,Filter 过滤器(十三)

    阅读本文前可先参考 ​​​​​​SpringCloud - Spring Cloud根/父项目,开发准备(二)_MinggeQingchun的博客-CSDN博客 SpringCloud - Spring Cloud 之 Gateway网关(十三)_MinggeQingchun的博客-CSDN博客 Web 有三大组件(监听器 过滤器 servlet),Spring Cloud GateWay 最主要的功能就是路由转发,而在定义

    2024年02月14日
    浏览(55)
  • Spring-Cloud-Gateway如何自定义路由过滤器?

    遇到这么一个面试题:自定义网关过滤器实现把url中的请求参数放到http的header中传递给微服务。 我们知道网关的一个重要的作用就是路由转发,路由表的配置大概是这个样子: 其中的filters就是配置的路由过滤器,Spring已经内置了31个路由的过滤器,这些过滤器都是 org.spring

    2024年02月16日
    浏览(32)
  • GateWay网关自定义过滤器实现token校验完成统一鉴权

    gateWay---API网关,也可以称为业务网关,主要服务于微服务的; (1)  三大组件 路由(Route)         构建网关的基本模块,由id(唯一标示)、目标URI、一组断言、一组过滤器组成,如果断言为true,则匹配该路由   断言(Predicate)          可以使用它匹配来自HTTP请求的任何

    2024年02月08日
    浏览(37)
  • 微服务Gateway网关(自动定位/自定义过滤器/解决跨域)+nginx反向代理gateway集群

    目录 Gateway网关 1.0.为什么需要网关? 1.1.如何使用gateway网关 1.2.网关从注册中心拉取服务 1.3.gateway自动定位 1.4.gateway常见的断言 1.5.gateway内置的过滤器 1.6.自定义过滤器-全局过滤器 1.7.解决跨域问题 2.nginx反向代理gateway集群 2.1.配置文件 继  nacos注册中心+Ribbon负载均衡+完成

    2024年02月06日
    浏览(56)
  • gateway-过滤器执行顺序

    请求进入网关会碰到三类过滤器:当前路由过滤器、DefaultFilter、GlobalFilter。 请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器 过滤器执行顺序 1.每一个过滤器都必须指定一个int类型的order值,order值越小

    2024年02月13日
    浏览(37)
  • Gateway网关 全局过滤器

    一、全局过滤器 全局过滤器GlobalFilter 全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。 区别在于GatewayFilter通过配置定义,处理逻辑是固定的。 需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件: 参数中是否有au

    2024年02月07日
    浏览(39)
  • 网关Gateway过滤器的使用

    前言: 最近在学习微服务相关的知识,看了黑马的相关课程,将关于Gateway过滤器的知识又总结了一些,希望能帮到各位小伙儿们以及加深下自己的印象🎊 如果文章有什么需要改进的地方还请大佬多多指教🥂 小威先感谢大家的支持了😁 Gateway网关的过滤器分为两种,一种是

    2023年04月09日
    浏览(34)
  • gateway之过滤器(Filter)详解

    在Spring Cloud中,过滤器(Filter)是一种关键的组件,用于在微服务架构中处理和转换传入请求以及传出响应。过滤器位于服务网关或代理中,并通过拦截请求和响应流量来提供各种功能。 过滤器在请求的不同生命周期阶段执行特定的操作,例如鉴权、认证、请求转发、限流、

    2024年02月05日
    浏览(33)
  • gateway过滤器没生效,特殊原因

    看这边文章的前提,你要会gateway,知道过滤器怎么配置? 直接来看过滤器,局部过滤器 再来看配置 请求路径 http://127.0.0.1:8080/appframework/services/catalog/catalogSpecials.json?pageindex=1pagesize=10pkid=d9873700ef7e42b3b8f4e782f345975b 看起来确实没什么问题 注意: 我这里还有个应用,就是网关转

    2024年02月14日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包