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
是用来设置限流的阈值,你可以根据需要调整。
固定容量的令牌桶: 令牌桶内有固定数量的令牌,这些令牌以固定的速率被添加到桶中。
令牌添加速率: 令牌以恒定的速率(例如每秒添加固定数量的令牌)被添加到令牌桶中。
令牌消耗: 当请求到达时,需要从令牌桶中获取一个令牌。如果令牌桶中有足够的令牌,则请求被允许处理,并消耗一个令牌;否则,请求被限流。
平滑限流: 由于令牌以恒定速率被添加,令牌桶算法可以实现平滑限流,即请求被均匀地处理,而不是突然被拒绝。
适应突发流量: 令牌桶算法对于处理突发流量也具有一定的适应性,因为即使令牌桶空了一段时间,一旦有令牌被添加,就可以处理新的请求。
容错性好: 由于令牌桶算法是基于时间的,因此对于时间敏感的应用来说,容错性较好。而且由于每个请求都需要从令牌桶中获取令牌,因此可以有效防止突发请求对系统的影响。
三、区别
-
设计用途:
- GatewayFilter: 用于定义网关过滤器的行为,是一个简单的接口。每个过滤器的实现需要直接实现
GatewayFilter
接口中的方法。 - AbstractGatewayFilterFactory: 是一个抽象类,旨在更方便地创建具有配置参数的网关过滤器。通过继承这个抽象类,你可以更容易地处理配置参数的解析和过滤器实例的创建。
-
用法:
- GatewayFilter: 直接实现
GatewayFilter
接口,编写过滤器逻辑。这种方式适用于不需要配置参数的简单过滤器。 - AbstractGatewayFilterFactory: 继承该抽象类,实现抽象方法
apply
和apply(C config, Class<C> configClass)
,并在其中处理配置参数并创建过滤器实例。这种方式适用于需要配置参数的过滤器。
-
配置参数:
- GatewayFilter: 如果过滤器需要配置参数,需要通过其他方式(如构造函数、属性注入等)传递参数,因为
GatewayFilter
接口本身不提供直接的配置机制。 - AbstractGatewayFilterFactory: 通过泛型参数
C
指定配置参数的类型,并在apply
方法中接收配置参数。这使得配置参数的处理更为灵活,Spring Cloud Gateway 会负责将配置参数绑定到过滤器实例。
相关文章:
SpringCloud GateWay自定义过滤器之GatewayFilter和AbstractGatewayFactory
一、GatewayFilter GatewayFilter 是一个简单的接口,用于定义网关过滤器的行为。一个网关过滤器就是一个实现了 GatewayFilter 接口的类,它可以执行在请求进入网关或响应离开网关时的某些操作。过滤器可以用于修改请求或响应,记录日志&#…...

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

程序员副业接单做私活避坑指南
不建议大家在接单这个事情上投入太大精力,如果你“贼心不改”,建议大家以比较随缘的方式对待这件事情。 接单平台 下文是接单平台,内容来自知乎,转载过来的原因有2个: 方便大家了解这些平台各自的优势,可以…...
day57
今日内容概要 模板层 模板之过滤器 模板之标签(if else for) 模板之继承 导入模板 模型层 单表的操作 十几种常见的查询方法 基于下划线的查询方法 外键字段的增删改查 正反向查询(多表跨表) 模板之过滤器 语法: {{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 使…...

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

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

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

大数据-之LibrA数据库系统告警处理(ALM-12047 网络读包错误率超过阈值)
告警解释 系统每30秒周期性检测网络读包错误率,并把实际错误率和阈值(系统默认阈值0.5%)进行比较,当检测到网络读包错误率连续多次(默认值为5)超过阈值时产生该告警。 用户可通过“系统设置 > 阈值配置…...

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的启动端口和管理端口(没有这个需求就不用看了)七、需要注意版本问题可能遇到的错误和解决方式version GLIBC_2.34 类型错误undefined function rab…...

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

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

candence出现no connect property onpin,,,,错误,该怎么办?
原因是上面有引脚添加了 属性no connect,但依然连接了网络,这个时候需要把线剪切,然后看到引脚上有个X, 解决方法: 工具栏"place >no connect "X 再连上线,再生成网标的时候, 就不报错了…...

Elasticsearch:Lucene 中引入标量量化
作者:BENJAMIN TRENT 我们如何将标量量化引入 Lucene。 Lucene 中的自动字节量化 虽然 HNSW 是一种强大而灵活的存储和搜索向量的方法,但它确实需要大量内存才能快速运行。 例如,查询 768 维的 1MM float32 向量大约需要 1,000,000*4*(7681…...
如何做好测试用例设计
做好测试用例设计是确保软件质量的重要环节之一。以下是一些建议,可以帮助您设计出高效、全面和可靠的测试用例: 明确测试目标和需求 在开始设计测试用例之前,要明确测试的目标和需求,包括测试的范围、重点、预期结果等。这有助于…...
云计算是否正在“杀死”运维
一、云计算正在杀死运维吗? 随着云计算的发展,企业上云已经成为一种趋势。企业上云的初衷是把复杂的IT基础设施交给云平台去管理,企业可以专注于业务与应用、从而降低企业IT运营成本,提高IT部门工作效率。 因此有人会误以为&…...

2760. 最长奇偶子数组 : 抽丝剥茧,图解双指针做法正确性
题目描述 这是 LeetCode 上的 「2698. 求一个整数的惩罚数」 ,难度为 「简单」。 Tag : 「双指针」、「滑动窗口」 给你一个下标从 开始的整数数组 nums 和一个整数 threshold。 请你从 nums 的子数组中找出以下标 l 开头、下标 r 结尾 ( ) 且满足以下条件的 最长子…...
在Linux系统中创建虚拟串口
在Linux系统中创建虚拟串口 文章目录 在Linux系统中创建虚拟串口1、虚拟串口介绍2、使用 socat创建虚拟串行端口2.1 安装socat2.2 创建简单的虚拟串口2.3 创建指定波特率的串行端口 有多种方法可以在 Linux 中创建虚拟串口来测试和调试串行通信协议。 在本文中,我们…...
无线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.扫描…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...