常见的限流算法
常见的限流算法
- 限流的定义
- 固定窗口算法
- 滑动窗口算法
- 漏桶算法(推荐)
- 令牌桶算法(推荐)
- 限流粒度
- 本地限流(单机限流)
- 分布式限流(多机限流)
- 分布式限流的实现
限流的定义
限流,也称流量控制。是指系统在面临高并发,或者大流量请求的情况下,限制新的请求对系统的访问,从而保证系统的稳定性。限流会导致部分用户请求处理不及时或者被拒,这就影响了用户体验。所以一般需要在系统稳定和用户体验之间平衡一下。
一般对于一些调用需要付费的接口,对用户进行限流操作,限制用户的请求次数。
比如:限制单个用户每秒只使用一次
固定窗口算法
单位时间内允许部分操作
维护一个计数器,将单位时间段当做一个窗口,计数器记录这个窗口接收请求的次数。
当次数少于限流阀值,就允许访问,并且计数器+1 当次数大于限流阀值,就拒绝访问。
当前的时间窗口过去之后,计数器清零,开始下一个窗口。
假设单位时间是1秒,限流阀值为3。在单位时间1秒内,每来一个请求,计数器就加1,如果计数器累加的次数超过限流阀值3,后续的请求全部拒绝。等到1s结束后,计数器清0,重新开始计数
优点:实现简单
缺点:会出现流量突刺

滑动窗口算法
单位时间内允许部分操作,但这个单位时间是滑动的,需要指定一个滑动单位。
优点:解决了流量突刺问题
缺点:实现较麻烦,很难找到准确的滑动单位,滑动单位越小,效果越好。

漏桶算法(推荐)
以固定速率处理请求(漏水操作),当请求桶满了之后,就拒绝请求

优点:在一定程度上能够应对流量突刺,以固定速率处理请求,能够保证服务器的安全
缺点:无法迅速的对请求做出处理,只能一个个按顺序处理(固定速率处理的缺点)
令牌桶算法(推荐)
以固定速率向令牌桶添加令牌,每个令牌代表一定数量的请求,请求需要获取令牌之后才能够被处理。没有令牌的请求会被拒绝。
优点:能够并发的处理请求,并发的性能会更高一点。
缺点:还是存在时间单位选取的问题
限流粒度
1.针对某个方法进行限流,单位时间内最多允许XXX个操作使用使用这个方法。
2,针对某个用户进行限流,某个用户单位时间内最多执行XXX个操作
3.针对某个用户X方法,单个用户单位时间内最多执行XXX次这个方法
本地限流(单机限流)
这里采用谷歌的Guava RateLimiter实现
import com.google.common.util.concurrent.RateLimiter;public static void main(String[] args) {// 每秒限流5个请求RateLimiter limiter = RateLimiter.create(5.0);while (true) {if (limiter.tryAcquire()) {// 处理请求} else {// 超过流量限制,需要做何处理}}
}
分布式限流(多机限流)
如果你的项目有多个服务器,比如微服务,那么建议使用分布式限流。
1.把用户的使用频率等数据放到一个集中的存储进行统计;比如Redis,这样无论用户的
请求落到了哪台服务器,都以集中存储中的数据为准。(Redisson --是一个操作 Redis 的工具库)
2.在网关集中进行限流和统计(比如 Sentinel、Spring Cloud Gateway)
import org.redisson.Redisson;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;public static void main(String[] args) {// 创建RedissonClientRedissonClient redisson = Redisson.create();// 获取限流器RSemaphore semaphore = redisson.getSemaphore("mySemaphore");// 尝试获取许可证boolean result = semaphore.tryAcquire();if (result) {// 处理请求} else {// 超过流量限制,需要做何处理}
}
分布式限流的实现
redission配置
package com.cheng.config;import org.redisson.config.Config;
import lombok.Data;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@ConfigurationProperties(prefix = "spring.redis")
@Data
public class RedissonConfig {private String host;private Integer port;private Integer database;private String password;@Beanpublic RedissonClient redissonClient() {Config config = new Config();config.useSingleServer().setAddress("redis://" + host + ":" + port).setDatabase(database).setPassword(password);return Redisson.create(config);}
}
RedisLimiterManager服务的实现
package com.cheng.manager;import com.cheng.common.ErrorCode;
import com.cheng.exception.BusinessException;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** 专门提供 RedisLimiter 限流基础服务*/
@Service
public class RedisLimiterManager {@Resourceprivate RedissonClient redissonClient;/*** 采用令牌桶限流算法* 每个用户一个限流器** 限流操作** @param key 区分不同的限流器,比如不同的用户 id 应该分别统计*/public void doRateLimit(String key) {// 创建一个名称为user_limiter的限流器,每秒最多访问 2 次RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);//RateType.OVERALL 统一速率,全局的rateLimiter.trySetRate(RateType.OVERALL, 2, 1, RateIntervalUnit.SECONDS);// 每当一个操作来了后,请求一个令牌boolean canOp = rateLimiter.tryAcquire(1);if (!canOp) {throw new BusinessException(ErrorCode.REQUEST_OVER);}}
}
测试类
package com.cheng.springbootinit.manager;import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;import static org.junit.jupiter.api.Assertions.*;@SpringBootTest
class RedisLimiterManagerTest {@Resourceprivate RedisLimiterManager redisLimiterManager;@Testvoid doRateLimit() throws InterruptedException {// 模拟一下操作String userId = "1";// 瞬间执行2次,每成功一次,就打印'成功'for (int i = 0; i < 2; i++) {redisLimiterManager.doRateLimit(userId);System.out.println("成功");}// 睡1秒Thread.sleep(1000);// 瞬间执行5次,每成功一次,就打印'成功'for (int i = 0; i < 5; i++) {redisLimiterManager.doRateLimit(userId);System.out.println("成功");}}
}相关文章:
常见的限流算法
常见的限流算法 限流的定义固定窗口算法滑动窗口算法漏桶算法(推荐)令牌桶算法(推荐)限流粒度本地限流(单机限流)分布式限流(多机限流)分布式限流的实现 限流的定义 限流,也称流量控制。是指系统…...
【Leetcode 每日一题】3159. 查询数组中元素的出现位置
问题背景 给你一个整数数组 n u m s nums nums,一个整数数组 q u e r i e s queries queries 和一个整数 x x x。 对于每个查询 q u e r i e s [ i ] queries[i] queries[i],你需要找到 n u m s nums nums 中第 q u e r i e s [ i ] queries[i] q…...
xadmin后台首页增加一个导入数据按钮
xadmin后台首页增加一个导入数据按钮 效果 流程 1、在添加小组件中添加一个html页面 2、写入html代码 3、在urls.py添加导入数据路由 4、在views.py中添加响应函数html代码 <!DOCTYPE html> <html lang...
行为树详解(5)——事件驱动
【分析】 如果行为树的节点很多,那么会存在要经过很多节点才会走到动作节点的情况。显然,性能上不如状态机。 每帧都需要重新遍历一系列节点才会走到动作节点,而实际上很多条件节点在数帧内不会有变化,这是造成性能问题的重要原…...
3.若依前端项目拉取、部署、访问
因为默认RuoYi-Vue是使用的Vue2,所以需要另外去下载vue3来部署。 拉取代码 git clone https://gitee.com/ys-gitee/RuoYi-Vue3.git 安装node才能执行npm相关的命令 执行命令npm install 如果npm install比较慢的话,需要添加上国内镜像 npm install --registrhttp…...
Debian操作系统相对于Ubuntu有什么优势吗?
更高的稳定性:Debian 以其出色的稳定性闻名,得益于严格的软件包测试和发布流程。其稳定版经过长时间测试与验证,确保了系统的高度稳定,更适合对稳定性要求极高的长期运行服务器环境。而 Ubuntu 虽有稳定版本,但更新周期…...
【漏洞复现】CVE-2015-3337 Arbitrary File Reading
漏洞信息 NVD - CVE-2015-3337 Directory traversal vulnerability in Elasticsearch before 1.4.5 and 1.5.x before 1.5.2, when a site plugin is enabled, allows remote attackers to read arbitrary files via unspecified vectors. 在安装了具有“site”功能的插件以…...
win10、win11-鼠标右键还原、暂停更新
系统优化 win 10jihuo win 11jihuo鼠标右键还原暂停更新 update 2024.12.28win 10 jihuo winx,打开powershell管理员,输入以下命令,选择1并等待 irm https://get.activated.win | iex参考:https://www.bilibili.com/video/BV1TN411M72J/?sp…...
FFmpeg来从HTTP拉取流并实时推流到RTMP服务器
当使用FFmpeg来从HTTP拉取流并实时推流到RTMP服务器时,你可以使用以下命令: ffmpeg -i http://输入流地址 -c:v copy -c:a copy -f flv rtmp://RTMP服务器地址/应用名称/流名称 这是一个基本的命令示例,其中: - -i http://输入流地…...
Quo Vadis, Anomaly Detection? LLMs and VLMs in the Spotlight 论文阅读
文章信息: 原文链接:https://arxiv.org/abs/2412.18298 Abstract 视频异常检测(VAD)通过整合大语言模型(LLMs)和视觉语言模型(VLMs)取得了显著进展,解决了动态开放世界…...
Rust : tokio中select!
关于tokio的select宏,有不少的用途。包括超时和竞态选择等。 关于select宏需要关注,相关的异步条件,会同时执行,只是当有一个最早完成时,会执行“抛弃”和“对应”策略。 说明:对本文以下素材的来源表示感…...
【hackmyvm】hacked靶机wp
tags: HMVrootkitDiamorphine Type: wp 1. 基本信息^toc 文章目录 1. 基本信息^toc2. 信息收集2.1. 端口扫描2.2. 目录扫描2.3. 获取参数 3. 提权 靶机链接 https://hackmyvm.eu/machines/machine.php?vmHacked 作者 sml 难度 ⭐️⭐️⭐️⭐️️ 2. 信息收集 2.1. 端口扫描…...
MaixBit k210学习记录
开发背景:Window系统主机,在主机上安装了虚拟机(VirtualBoxUbuntu23.04) 目标实现:在虚拟机(Ubuntu)中,实现对Maix bit(k210)开发板的开发 虚拟机的安装参考…...
Wordperss漏洞 DeDeCMS漏洞
Wordperss漏洞 环境搭建 #执⾏命令 cd /vulhub/wordpress/pwnscriptum docker-compose up -d #靶场地址 http://8.155.7.173:8080/wp-admin/ 注册账号 登录 漏洞一:后台修改模板拿WebShell 步骤一:思路是修改其WP的模板写入⼀句话木马后门并访问其文件…...
如何构建有效的AI Agents:从复杂到简约——深度解读Claude实践总结《Building effective agents》(上)
在人工智能技术日新月异的今天,大语言模型(LLM)已经成为技术创新的热点。 然而,在追逐技术前沿的热潮中,我们是否忽视了工程设计的本质? 作为全球人工智能领域的领军企业之一,Anthropic以其在AI安全和伦理方面的深入…...
git status 耗时
某个git库每次status一下就是半小时起步,gc后还是没有效果,后来排查记录发现某笔记录提交几百G的冗余文件,虽然revert了,但是还是存在库中,遂如下清理: # 查找大文件 git verify-pack -v .git/objects/pac…...
C++进阶重点知识(一)|智能指针|右值|lambda|STL|正则表达式
目录 1智能指针1.shared_ptr1.1 shared_ptr的基本用法使用shared_ptr要注意的问题运用 2.unique_ptr独占的智能指针示例:管理动态内存 3.weak_ptr弱引用的智能指针weak_ptr的基本用法lock 的作用:weak_ptr返回this指针weak_ptr解决循环引用问题weak_ptr使…...
OSCP打靶大冒险之Solidstate:多端口获取信息,shell逃逸,计划任务提权
声明! 学习资源来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&a…...
八股(One Day one)
最近老是看到一些面试的视频,对于视频内部面试所提到的八股文,感觉是知道是什么,但是要说的话,却又不知道该怎么说(要不咋称之为八股文呢),所以就想到写一篇八股文总结的博客,以便进…...
如何快速又安全的实现端口转发【Windows MAC linux通用】
背景 有很多程序是在虚拟机上运行的,返回的url 又是127.0.0.1。在个人电脑上调试需要解决这个问题。端口转发是一个不错的方法 可能的解决办法: 1.修改程序,返回虚拟机的ip (要改代码,换虚拟机还要再改代码…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...
2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版
1.题目描述 2.思路 当前的元素可以重复使用。 (1)确定回溯算法函数的参数和返回值(一般是void类型) (2)因为是用递归实现的,所以我们要确定终止条件 (3)单层搜索逻辑 二…...
