【自研网关系列】过滤器链 -- 限流过滤器

🌈Yu-Gateway:基于 Netty 构建的自研 API 网关,采用 Java 原生实现,整合 Nacos 作为注册配置中心。其设计目标是为微服务架构提供高性能、可扩展的统一入口和基础设施,承载请求路由、安全控制、流量治理等核心网关职能。

🌈项目代码地址:https://github.com/YYYUUU42/YuGateway-master

如果该项目对你有帮助,可以在 github 上点个 ⭐ 喔 🥰🥰

🌈自研网关系列:可以点开专栏,参看完整的文档

目录

1、限流配置

2、实现流程

Redis 固定窗口限流

Guava 单机限流

3、限流压测


1、限流配置

nacos 上的配置:

type:匹配的类型(根据路径或者服务名称)

value:路径或者服务名

model:限流方式(单机或者分布式)

algorithm:限流算法(固定窗口、令牌桶)

duration:限流时间单位(秒)

permits:限流请求次数(次)

    {"id": "http-server","name": "http-server","paths": ["/http-server/ping","/http-server/gray"],"prefix": "/http-server","protocol": "http","retryConfig": {"times": 3},"serviceId": "backend-http-server","filterConfigs": [{"config": {"load_balance": "RoundRobin"},"id": "load_balance_filter"},{"id": "auth_filter"},{"id": "gray_filter"},{"id": "flow_ctl_filter"}],"flowControlConfigs": [ {"type": "path","value": "/http-server/ping","mode": "distributed","algorithm": "fixed_window","config": {"duration": 1,"permits": 10}} ]}

2、实现流程

继续通过debug的方式来讲述流程,由于类比较多,就不展示代码,在 github 上 clone 代码执行查看

首先还是从 nacos 中读取 Rule 规则,得到限流的配置,这里是可以制定多个限流规则的,每个 url 都可以自己的限流规

这一步的主要作用是获取一个 FlowControlByPathRule 的实例,这样做的目的是为了实现对每个服务路径的流量控制,每个服务路径都有一个对应的 FlowControlByPathRule 实例,用于处理该路径的流量控制规则,也算是单例设计模式的一种运用

if (flowControlConfig.getType().equalsIgnoreCase(FilterConst.FLOW_CTL_TYPE_PATH)&& path.equals(flowControlConfig.getValue())) {flowControlRule = FlowControlByPathRule.getInstance(rule.getServiceId(), path);
}

这里根据服务ID和请求路径,以及从配置中心获取的限流配置,来执行具体的流控操作

if (flowControlConfig == null || StringUtils.isEmpty(serviceId) || StringUtils.isEmpty(flowControlConfig.getConfig())) {return;
}
//获得当前路径对应的流控次数
Map<String, Integer> configMap = JSON.parseObject(flowControlConfig.getConfig(), Map.class);//判断是否包含流控规则   FLOW_CTL_LIMIT_DURATION:限流时间单位---秒  FLOW_CTL_LIMIT_PERMITS:限流请求次数---次
if (!configMap.containsKey(FLOW_CTL_LIMIT_DURATION) || !configMap.containsKey(FLOW_CTL_LIMIT_PERMITS)) {return;
}//得到流控时间和时间内限制次数
double duration = configMap.get(FLOW_CTL_LIMIT_DURATION);
double permits = configMap.get(FLOW_CTL_LIMIT_PERMITS);//当前请求是否触发流控标志位
boolean flag = false;
String key = serviceId + "." + path;//如果是分布式项目 那么我们就需要使用Redis来实现流控  单机则可以直接使用Guava
if (FilterConst.FLOW_CTL_MODE_DISTRIBUTED.equalsIgnoreCase(flowControlConfig.getMode())) {flag = switch (flowControlConfig.getAlgorithm()) {case VOTE_BUCKET_ALGORITHM -> new VoteBucketAlgorithm(new JedisUtil()).executeResp(flowControlConfig);case FIXED_WINDOWS_ALGORITHM -> new StableAlgorithm(new JedisUtil()).executeResp(flowControlConfig);default -> new VoteBucketAlgorithm(new JedisUtil()).executeResp(flowControlConfig);};
} 

Redis 固定窗口限流

/*** @param limit      请求限制数量* @param windowSize 窗口大小*/
public boolean isAllowed(String id, int limit, int windowSize) {String lockKey = PREFIX + ":" + "LOCK" + ":" + id;// 窗口初始化try {boolean isLock = jedisUtil.getDistributeLock(lockKey, id, windowSize);if (isLock) {String window_key = PREFIX + ":" + id;long current = jedisUtil.increment(window_key);if (current == 1) {jedisUtil.setExpire(window_key, windowSize);}return current <= limit;}} finally {jedisUtil.releaseDistributeLock(lockKey, id);}return false;
}

Guava 单机限流

主要就是通过 Guava 库中的 RateLimiter 类来实现限流

/*** 获取令牌** @param permits 需要获取的令牌数量* @return 是否获取成功*/
public boolean acquire(int permits) {return rateLimiter.tryAcquire(permits);
}

3、限流压测

这里的话,网关限流配置是 1 秒 10个请求

jmeter 设置 1 秒 100 个请求,结果树显示只有 10 个请求响应成功,剩下的请求失败

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/6067.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESP32-C3模组上跑通MQTT(1)

本文内容参考&#xff1a; 《ESP32-C3 物联网工程开发实战》 特此致谢&#xff01; 一、远程控制的介绍 什么是远程控制&#xff1f;顾名思义&#xff0c;远程控制就是远距离控制&#xff0c;是指控制设备&#xff08;如智能手机、计算机等网络设备&#xff09;通过广域网控制…

DLNA源码分析之render设备注册

1&#xff0c;概述 DLNA设备、服务的注册及发现&#xff08;依赖开源库cling&#xff09;&#xff0c;DLNA中设备的注册、发现主要基于UPNP协议实现&#xff0c;这是微软推行的一个标准。Upnp最大的愿景是希望任何设备只要一接入网络&#xff0c;所有网上的设备马上就能知道有新…

FIFO Generate IP核使用——FIFO写操作详解及Status Flags页配置

本文介绍了FIFO的写操作及Status Flags页的配置信息。 1 FIFO 写入操作 当FIFO的写入使能&#xff08;write enable&#xff09;被置位&#xff0c;并且FIFO未满时&#xff0c;数据会从输入总线&#xff08;din&#xff09;被添加到FIFO中&#xff0c;并且写入确认&#xff0…

Mac环境下ollama部署和体验

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 关于ollama ollama和LLM&#xff08;大型语言模型&#xff09;的关系&#xff0c;类似于docker和镜像&#xff0c;可以在ollama服务中管理和运行各种LLM&…

逻辑漏洞:支付逻辑漏洞

目录 1、直接修改商品的价格 2、修改支付状态 3、修改商品数量 4、另类支付 5、修改支付接口 6、重复支付 7、最小支付和最大支付 8、越权支付 9、无线次试用 10、线程并发问题 前两天学习了逻辑漏洞中的越权漏洞&#xff0c;今天开始学习支付逻辑漏洞&#xff0c;这…

数据分析--客户价值分析RFM(分箱法/标准化)

原数据 原数据如果有异常或者缺失等情况&#xff0c;要先对数据进行处理 &#xff0c;再进行下面的操作&#xff0c;要不然会影响结果的正确性 一、根据RFM计算客户价值并对客户进行细分 1. 数据预处理 1.1 创建视图存储 R、F、M的最大最小值 创建视图存储R 、F、M 的最大最小…

云计算技术概述_2.云计算的服务方式

1.三类典型的服务方式 在对云计算深入理解的基础上&#xff0c;产业界和学术界对云计算的服务方式进行了总结。目前一致认为云计算自上而下具有“软件即服务&#xff08;Software as a Service&#xff09;”、“平台即服务&#xff08;Platform as a Service&#xff0c;Paas&…

Sublime Vim模式配置:q关闭当前标签页

在Sublime安装目录下的->Packages文件夹下新建User文件夹创建文件Vintage.sublime-commands 路径为Sublime安装目录->Packages->User->Vintage.sublime-commands文件内容如下[{"caption": ":w - Save","command": "save"}…

淘宝新店铺一般多久开始有单

淘宝新店铺一般多久开始有单 淘宝推广可以使用3an推客。3an推客&#xff08;CPS模式&#xff09;给商家提供的营销工具&#xff0c;由商家自主设置佣金比例&#xff0c;激励推广者去帮助商家推广商品链接&#xff0c;按最终有效交易金额支付佣金&#xff0c;不成交不扣费。是商…

前端框架比较,vue,react,angular该如何选择?

Vue.js、React和Angular这三种流行前端框架的详细比较&#xff1a; Vue.js&#xff1a; 优点&#xff1a; Vue.js 的采用了一个渐进式的设计模型&#xff0c;意味着开发者可以只选择自己需要的模块进行开发&#xff0c;这让Vue.js较为轻巧和灵活。学习曲线相对较低&#xff0c;…

堆排序以及TOP-K问题

片头 嗨&#xff01;小伙伴们&#xff0c;大家好&#xff01;今天我们来深入理解堆这种数据结构&#xff0c;分析一下堆排序以及TOP-K问题&#xff0c;准备好了吗&#xff1f;我要开始咯&#xff01; 一、堆排序 这里我们先假设要排成升序&#xff0c;也就是从左到右&#xf…

php字符串变量和常见的字符串函数

在 PHP 中&#xff0c;字符串变量用于存储文本数据。你可以使用单引号&#xff08;&#xff09;、双引号&#xff08;"&#xff09;或定界符&#xff08;heredoc 或 nowdoc&#xff09;来定义字符串。下面是一些关于 PHP 字符串变量的重要点和示例&#xff1a; 1. 单引号…

【Leetcode每日一题】 动态规划 - 简单多状态 dp 问题 - 删除并获得点数(难度⭐⭐)(70)

1. 题目解析 题目链接&#xff1a;740. 删除并获得点数 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 问题分析 本题是「打家劫舍」问题的变种&#xff0c;但核心逻辑依然保持一致。题目要求从给定的数组nums中选择…

QT-this关键字

在 C 中&#xff0c; this 关键字是一个指向调用对象的指针。它在成员函数内部使用&#xff0c;用于引用调用该函数的 对象。使用 this 可以明确指出成员函数正在操作的是哪个对象的数据成员。 #include <iostream>#include <string>using namespace std;class Ca…

【面试经典 150 | Kadane】环形子数组的最大和

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;求最大非空子数组和最小子数组和 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及…

Pytorch框架下的CNN和RNN

1.CNN 建立了3层&#xff08;3层2层1层全连接层&#xff09;。分别是conv1、conv2和分类问题中的全连接层线性层out class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 nn.Sequential( # input shape (1, 28, 28)nn.Conv2d(in_channe…

C++:输入输出运算符重载

在C中&#xff0c;输入输出运算符是用于从标准输入设备&#xff08;通常是键盘&#xff09;读取数据或将数据输出到标准输出设备&#xff08;通常是屏幕&#xff09;的运算符。常用的输入输出运算符包括&#xff1a; 输入运算符 (>>)&#xff1a; 用于从输入流&#xff0…

逻辑漏洞:水平越权、垂直越权靶场练习

目录 1、身份认证失效漏洞实战 2、YXCMS检测数据比对弱&#xff08;水平越权&#xff09; 3、MINICMS权限操作无验证&#xff08;垂直越权&#xff09; 1、身份认证失效漏洞实战 上一篇学习了水平越权和垂直越权的相关基本知识&#xff0c;在本篇还是继续学习&#xff0c;这…

深度学习:基于Keras,使用长短期记忆人工神经网络模型(LSTM)对股票市场进行预测分析

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

Electron-Builder 打包 Vue 项目避坑指南

最近在开发一个基于 Vue 的 Electron 项目&#xff0c;在打包时遇到了诸多问题&#xff0c;为了解决这些问题也查阅了非常多的资料&#xff0c;排除了很多坑。现在将可能遇到的问题整理成避坑指南&#xff0c;供大家参考&#xff08;此避坑指南后续还会继续更新&#xff09;。 …