当前位置: 首页 > news >正文

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

一、GatewayFilter

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

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

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

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

配置:

@Configuration
public class MyConfig {/**配置自定义过滤器*/@Beanpublic 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);}@Overridepublic 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);}@Overridepublic 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_routeuri: http://example.comfilters:- RateLimitByIp=1predicates:- 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. 配置参数:

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

相关文章:

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

一、GatewayFilter GatewayFilter 是一个简单的接口&#xff0c;用于定义网关过滤器的行为。一个网关过滤器就是一个实现了 GatewayFilter 接口的类&#xff0c;它可以执行在请求进入网关或响应离开网关时的某些操作。过滤器可以用于修改请求或响应&#xff0c;记录日志&#…...

不会英语能学编程吗?0基础学编程什么软件好?

不会英语能学编程吗&#xff1f;0基础学编程什么软件好&#xff1f; 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#xff0c;而且可以开发大型的软件&#xff0c;象如图这个…...

程序员副业接单做私活避坑指南

不建议大家在接单这个事情上投入太大精力&#xff0c;如果你“贼心不改”&#xff0c;建议大家以比较随缘的方式对待这件事情。 接单平台 下文是接单平台&#xff0c;内容来自知乎&#xff0c;转载过来的原因有2个&#xff1a; 方便大家了解这些平台各自的优势&#xff0c;可以…...

day57

今日内容概要 模板层 模板之过滤器 模板之标签(if else for) 模板之继承 导入模板 模型层 单表的操作 十几种常见的查询方法 基于下划线的查询方法 外键字段的增删改查 正反向查询(多表跨表) 模板之过滤器 语法&#xff1a; {{obj|filter__name:param}} 变量名字|…...

以太坊链多节点本地化【最详细的部署搭建及维护文档】

文章目录 一、维护人员素养1.1 岗位技能1.2 人员素质二、区块链节点及区块链浏览器搭建2.1 编写说明2.1.1 文档说明2.1.2 配置信息2.1.3 部署文档信息2.2 node环境安装2.2.1 基础命令安装2.2.2 安装node2.3 centos7 部署docker环境2.3.1 卸载旧版本2.3.2 使用 yum 安装2.3.3 使…...

微服务架构演进

系统架构演变 没有最好的架构&#xff0c;只有最合适的架构&#xff1b;架构发展过程&#xff1a;单体架构》垂直架构》SOA 面向服务架构》微服务架构&#xff1b;推荐看看《淘宝技术这十年》&#xff1b; 单体架构 互联网早期&#xff0c;一般的网站应用流量较小&#xff0…...

BUUCTF 九连环 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 下载附件&#xff0c;解压得到一张.jpg图片。 密文&#xff1a; 解题思路&#xff1a; 1、一张图片&#xff0c;典型的图片隐写。放到Kali中&#xff0c;使用binwalk检测&#xff0c;确认图片中隐藏zip压缩包。 使…...

编码自动化:使用MybatisX初体验,太爽了!

使用Mybatis当前最火的插件&#xff1a;MybatisX。 在IDEA中安装MyBatisX插件。 该插件主要功能如下&#xff1a; 生成mapper xml文件 快速从代码跳转到mapper及从mapper返回代码 mybatis自动补全及语法错误提示 集成mybatis Generate GUI界面 根据数据库注解&#xff0c;…...

大数据-之LibrA数据库系统告警处理(ALM-12047 网络读包错误率超过阈值)

告警解释 系统每30秒周期性检测网络读包错误率&#xff0c;并把实际错误率和阈值&#xff08;系统默认阈值0.5%&#xff09;进行比较&#xff0c;当检测到网络读包错误率连续多次&#xff08;默认值为5&#xff09;超过阈值时产生该告警。 用户可通过“系统设置 > 阈值配置…...

JSP 报错 Cannot resolve method ‘print(java.lang.String)‘问题解决

这里 我写了一段比较基础的代码 <%// 定义局部变量String message "Hello, JSP!";out.print(message); %>但是 项目跑起来又是可以的 其实就是缺少了 JAR包 依赖 我们 可以在项目环境中找到 pom.xml dependencies标签内 加入 如下代码 <dependency>…...

Linux系统下安装RabbitMQ超简单教程(非详细)(Centos8)

文章目录 一、下载所需安装包二、安装三、启动rabbitmq四、添加远程用户五、图形化访问六、修改rabbitmq的启动端口和管理端口&#xff08;没有这个需求就不用看了&#xff09;七、需要注意版本问题可能遇到的错误和解决方式version GLIBC_2.34 类型错误undefined function rab…...

2024江苏专转本流程与时间节点

2024江苏专转本考生&#xff0c;提前看一下转本的流程与时间节点&#xff01;适用于江苏三年制、五年一贯制专转本考试&#xff1a; 1. 专转本工作通知&#xff08;2023年12月上旬&#xff09; 若无特殊情况&#xff0c;到12月中旬&#xff0c;江苏省教育厅会发布关于做好2024…...

全国各区县日照时长数据,逐月数据均有!

今天给大家分享的是全国各区县日照时长月数据&#xff0c;包括不同月份不同地区的日照时长。这些数据可以帮助我们了解不同地区在不同月份的日照情况&#xff0c;为能源利用、农业生产和气候变化研究提供参考。 基本信息 数据名称: 全国各区县日照时长月数据 数据格式: shpex…...

candence出现no connect property onpin,,,,错误,该怎么办?

原因是上面有引脚添加了 属性no connect&#xff0c;但依然连接了网络&#xff0c;这个时候需要把线剪切&#xff0c;然后看到引脚上有个X, 解决方法&#xff1a; 工具栏&#xff02;place >no connect "X 再连上线&#xff0c;再生成网标的时候&#xff0c; 就不报错了…...

Elasticsearch:Lucene 中引入标量量化

作者&#xff1a;BENJAMIN TRENT 我们如何将标量量化引入 Lucene。 Lucene 中的自动字节量化 虽然 HNSW 是一种强大而灵活的存储和搜索向量的方法&#xff0c;但它确实需要大量内存才能快速运行。 例如&#xff0c;查询 768 维的 1MM float32 向量大约需要 1,000,000*4*(7681…...

如何做好测试用例设计

做好测试用例设计是确保软件质量的重要环节之一。以下是一些建议&#xff0c;可以帮助您设计出高效、全面和可靠的测试用例&#xff1a; 明确测试目标和需求 在开始设计测试用例之前&#xff0c;要明确测试的目标和需求&#xff0c;包括测试的范围、重点、预期结果等。这有助于…...

云计算是否正在“杀死”运维

一、云计算正在杀死运维吗&#xff1f; 随着云计算的发展&#xff0c;企业上云已经成为一种趋势。企业上云的初衷是把复杂的IT基础设施交给云平台去管理&#xff0c;企业可以专注于业务与应用、从而降低企业IT运营成本&#xff0c;提高IT部门工作效率。 因此有人会误以为&…...

2760. 最长奇偶子数组 : 抽丝剥茧,图解双指针做法正确性

题目描述 这是 LeetCode 上的 「2698. 求一个整数的惩罚数」 &#xff0c;难度为 「简单」。 Tag : 「双指针」、「滑动窗口」 给你一个下标从 开始的整数数组 nums 和一个整数 threshold。 请你从 nums 的子数组中找出以下标 l 开头、下标 r 结尾 ( ) 且满足以下条件的 最长子…...

在Linux系统中创建虚拟串口

在Linux系统中创建虚拟串口 文章目录 在Linux系统中创建虚拟串口1、虚拟串口介绍2、使用 socat创建虚拟串行端口2.1 安装socat2.2 创建简单的虚拟串口2.3 创建指定波特率的串行端口 有多种方法可以在 Linux 中创建虚拟串口来测试和调试串行通信协议。 在本文中&#xff0c;我们…...

无线WiFi安全渗透与攻防(五) Kali使用mdk3攻击wifi(详细教程)以及相关周边知识

Kali使用mdk3攻击wifi(详细教程) 一. 网络安全--Kali使用mdk3攻击wifi(详细教程)一.前言二.准备1.网卡2.虚拟机3.系统三.原理1.原理2.步骤四.实战1.网卡设置1.1查看网卡1.2.切换网卡模式1.3再次查看网卡2.AP扫描3.mdk3创建虚拟wifi1.创建一个虚拟wifi2.创建大量wifi4.扫描…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...