服务器雪崩的应对策略之----限流
限流是一种控制流量的技术,旨在防止系统在高并发请求下被压垮。通过限流,可以确保系统在负载高峰期依然能保持稳定运行。常见的限流策略包括令牌桶算法、漏桶算法、计数器算法和滑动窗口算法。
常见的限流方法
- 1. 令牌桶算法 (Token Bucket Algorithm)
- 2. 漏桶算法 (Leaky Bucket Algorithm)
- 3. 计数器算法 (Counter Algorithm)
- 4. 滑动窗口算法 (Sliding Window Algorithm)
- 结论
1. 令牌桶算法 (Token Bucket Algorithm)
令牌桶算法是一种允许突发流量的限流算法。系统按照固定速率生成令牌,请求只有在获取到令牌后才能被处理。
原理:
- 系统按照固定速率往桶中添加令牌。
- 当桶满时,多余的令牌会被丢弃。
- 每个请求需要从桶中获取一个令牌,若令牌数量不足,请求被拒绝或等待。
示例代码:
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>class TokenBucket
{
public:TokenBucket(int rate, int burst) : rate(rate), burst(burst), tokens(0) {last_refill = std::chrono::steady_clock::now();}bool allow_request() {std::lock_guard<std::mutex> lock(mutex);refill();if (tokens > 0) {tokens--;return true;}return false;}private:void refill() {auto now = std::chrono::steady_clock::now();auto duration = std::chrono::duration_cast<std::chrono::seconds>(now - last_refill).count();tokens = std::min(burst, tokens + duration * rate);last_refill = now;}int rate; // 令牌生成速率int burst; // 桶的容量int tokens; // 当前令牌数量std::chrono::steady_clock::time_point last_refill;std::mutex mutex;
};int main()
{TokenBucket bucket(5, 10); // 每秒生成5个令牌,桶容量为10个令牌for (int i = 0; i < 20; ++i) {if (bucket.allow_request()) {std::cout << "Request " << i << " is allowed\n";} else {std::cout << "Request " << i << " is denied\n";}std::this_thread::sleep_for(std::chrono::milliseconds(200));}return 0;
}
2. 漏桶算法 (Leaky Bucket Algorithm)
漏桶算法是一种严格控制流量速率的限流算法。它将请求放入一个固定容量的桶中,并以固定速率处理请求,溢出的请求会被丢弃。
原理:
- 请求以任意速率进入桶。
- 桶以固定速率漏出请求进行处理。
- 如果桶满了,后续请求会被丢弃。
示例代码:
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <chrono>class LeakyBucket
{
public:LeakyBucket(int rate, int capacity) : rate(rate), capacity(capacity), water(0) {last_check = std::chrono::steady_clock::now();}bool allow_request() {std::lock_guard<std::mutex> lock(mutex);leak();if (water < capacity) {water++;return true;}return false;}private:void leak() {auto now = std::chrono::steady_clock::now();auto duration = std::chrono::duration_cast<std::chrono::seconds>(now - last_check).count();int leaked = duration * rate;if (leaked > 0) {water = std::max(0, water - leaked);last_check = now;}}int rate; // 漏出速率int capacity; // 桶的容量int water; // 当前水量std::chrono::steady_clock::time_point last_check;std::mutex mutex;
};int main()
{LeakyBucket bucket(1, 10); // 每秒处理1个请求,桶容量为10个请求for (int i = 0; i < 20; ++i) {if (bucket.allow_request()) {std::cout << "Request " << i << " is allowed\n";} else {std::cout << "Request " << i << " is denied\n";}std::this_thread::sleep_for(std::chrono::milliseconds(200));}return 0;
}
3. 计数器算法 (Counter Algorithm)
计数器算法是一种简单的限流策略,通过计数器在固定时间窗口内计数请求数量,如果超过限制,则拒绝请求。
原理:
- 在固定时间窗口内计数请求数量。
- 如果请求数量超过设定的阈值,则拒绝请求。
- 时间窗口结束后,重置计数器。
示例代码:
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>class CounterRateLimiter
{
public:CounterRateLimiter(int limit, int window_size) : limit(limit), window_size(window_size), count(0) {window_start = std::chrono::steady_clock::now();}bool allow_request() {std::lock_guard<std::mutex> lock(mutex);auto now = std::chrono::steady_clock::now();if (std::chrono::duration_cast<std::chrono::seconds>(now - window_start).count() >= window_size) {window_start = now;count = 0;}if (count < limit) {count++;return true;}return false;}private:int limit; // 时间窗口内允许的最大请求数int window_size; // 时间窗口大小(秒)int count; // 当前请求数std::chrono::steady_clock::time_point window_start;std::mutex mutex;
};int main()
{CounterRateLimiter limiter(5, 1); // 每秒最多处理5个请求for (int i = 0; i < 20; ++i) {if (limiter.allow_request()) {std::cout << "Request " << i << " is allowed\n";} else {std::cout << "Request " << i << " is denied\n";}std::this_thread::sleep_for(std::chrono::milliseconds(200));}return 0;
}
4. 滑动窗口算法 (Sliding Window Algorithm)
滑动窗口算法是计数器算法的改进版,通过滑动窗口精确统计请求数量,避免固定窗口带来的突发流量问题。
原理:
- 将时间窗口划分为多个小的子窗口。
- 记录每个子窗口的请求数量。
- 滑动窗口通过移动时间窗口来更新请求数量。
示例代码:
#include <iostream>
#include <vector>
#include <chrono>
#include <thread>
#include <mutex>class SlidingWindowRateLimiter
{
public:SlidingWindowRateLimiter(int limit, int window_size, int bucket_count) : limit(limit), window_size(window_size), bucket_count(bucket_count), buckets(bucket_count, 0), count(0) {last_check = std::chrono::steady_clock::now();}bool allow_request() {std::lock_guard<std::mutex> lock(mutex);slide_window();if (count < limit) {buckets[current_bucket]++;count++;return true;}return false;}private:void slide_window() {auto now = std::chrono::steady_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_check).count();int slide_count = duration * bucket_count / (window_size * 1000);if (slide_count > 0) {for (int i = 0; i < slide_count && count > 0; ++i) {current_bucket = (current_bucket + 1) % bucket_count;count -= buckets[current_bucket];buckets[current_bucket] = 0;}last_check = now;}}int limit; // 时间窗口内允许的最大请求数int window_size; // 时间窗口大小(秒)int bucket_count; // 子窗口数量std::vector<int> buckets; // 存储每个子窗口的请求数int count; // 当前请求总数int current_bucket = 0; // 当前子窗口索引std::chrono::steady_clock::time_point last_check;std::mutex mutex;
};int main()
{SlidingWindowRateLimiter limiter(5, 1, 10); // 每秒最多处理5个请求,划分为10个子窗口for (int i = 0; i < 20; ++i) {if (limiter.allow_request()) {std::cout << "Request " << i << " is allowed\n";} else {std::cout << "Request " << i << " is denied\n";}std::this_thread::sleep_for(std::chrono::milliseconds(200));}return 0;
}
结论
限流方法可以有效地保护系统免受过载的影响,确保系统在高并发情况下仍能稳定运行。通过选择适合的限流策略,可以根据不同场景和需求实现精确的流量控制。
相关文章:
服务器雪崩的应对策略之----限流
限流是一种控制流量的技术,旨在防止系统在高并发请求下被压垮。通过限流,可以确保系统在负载高峰期依然能保持稳定运行。常见的限流策略包括令牌桶算法、漏桶算法、计数器算法和滑动窗口算法。 常见的限流方法 1. 令牌桶算法 (Token Bucket Algorithm)2…...

Python12 列表推导式
1.什么是列表推导式 Python的列表推导式(list comprehension)是一种简洁的构建列表(list)的方法,它可以从一个现有的列表中根据某种指定的规则快速创建一个新列表。这种方法不仅代码更加简洁,执行效率也很…...

threejs 光影投射-与场景进行交互(六)
效果 场景中有三个立方体,三种颜色.点击变成红色,再点恢复自身原有颜色 代码 import ./style.css import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls.js import { log } from three/examples/jsm/nodes/Nodes.js//…...

Ubuntu 20.04安装显卡驱动、CUDA和cuDNN(2024.06最新)
一、安装显卡驱动 1.1 查看显卡型号 lspci | grep -i nvidia我们发现输出的信息中有Device 2230,可以根据这个信息查询显卡型号 查询网址:https://admin.pci-ids.ucw.cz/mods/PC/10de?actionhelp?helppci 输入后点击Jump查询 我们发现显卡型号为RTX …...

二叉树的这五种遍历方法你们都会了吗?
说在前面 🎈二叉树大家应该都很熟了吧,那二叉树的这五种遍历方式你们都会了吗? 以这一二叉树为例子,我们来看看不同遍历方式返回的结果都是怎样的。 前序遍历 前序遍历的顺序是:首先访问根节点,然后递归地…...

使用模数转换器的比例电阻测量基础知识
A/D 转换器是比率式的,也就是说,它们的结果与输入电压与参考电压的比值成正比。这可用于简化电阻测量。 测量电阻的标准方法是让电流通过电阻并测量其压降 (见图 1)。然后,欧姆定律(V I x R) 可用于计算电压和电流的…...

(C++语言的设计和演化) C++的设计理念
文章目录 前言📖C 语言设计规则📐规则和原理📐一般性规则📐设计支持规则📐语言的技术性规则📐低级程序设计支持规则 📖标准化(扩充评判准则)📐它精确吗&#…...

AI音乐:创新引擎还是创意终结者?
✨作者主页: Mr.Zwq✔️个人简介:一个正在努力学技术的Python领域创作者,擅长爬虫,逆向,全栈方向,专注基础和实战分享,欢迎咨询! 您的点赞、关注、收藏、评论,是对我最大…...
20240621每日后端---------如何优化项目中的10000个if-else 语句?
如何优化 10000 个 if-else 语句?有没有好的解决方案? 额,本身问题就很奇怪,怎么可能有这种代码。。。世界你让我陌生,但是我们还是假象着看看能不能解决一下。 解决方案1:策略模式 使用策略模式确实可以…...

【STM32】时钟树系统
1.时钟树简介 1.1五个时钟源 LSI是低速内部时钟,RC振荡器,频率为32kHz左右。供独立看门狗和自动唤醒单元使用。 LSE是低速外部时钟,接频率为32.768kHz的石英晶体。这个主要是RTC的时钟源。 HSE是高速外部时钟,可接石英*/陶瓷谐振…...

docker换源
文章目录 前言1. 查找可用的镜像源2. 配置 Docker 镜像源3. 重启 Docker 服务4. 查看dock info是否修改成功5. 验证镜像源是否更换成功注意事项 前言 在pull镜像时遇到如下报错: ┌──(root㉿kali)-[/home/longl] └─# docker pull hello-world Using default …...

百度在线分销商城小程序源码系统 分销+会员组+新用户福利 前后端分离 带完整的安装代码包以及搭建部署教程
系统概述 百度在线分销商城小程序源码系统是一款集分销、会员组管理和新用户福利于一体的前后端分离的系统。它采用先进的技术架构,确保系统的稳定性、高效性和安全性。该系统的前端基于小程序开发,为用户提供了便捷的购物体验和交互界面。用户可以通过…...

Flutter【组件】富文本组件
简介 flutter 富文本组件。 github地址: https://github.com/ThinkerJack/jac_uikit pub地址:https://pub.dev/packages/jac_uikit 使用方式 运行 flutter pub add jac_uikit组件文档 使用方式: HighlightedTextWidget.builder(text: &…...

中国恋爱交友相亲软件有哪些?大型婚恋相亲交友APP真实测评推荐
嘿嘿,当了29年的单身汪,这下总算不再单着啦!这两年把身边能找的人都找遍了,也没碰到合适的。没办法,就跑到网上去试试,坚持了有半年,可算有对象啦!下面给大家说说我用过的几个能脱单…...

快速欧氏聚类与普通欧氏聚类比较
1、前言 文献《FEC: Fast Euclidean Clustering for Point Cloud Segmentation》介绍了一种快速欧氏聚类方法,大概原理可以参考如下图,具体原理可以参考参考文献。 2、时间效率比较:快速欧氏聚类VS普通欧氏聚类 网上搜集的快速欧式聚类,与自己手写的普通欧式聚类进行对比,…...
如何让大语言模型在规格普通的硬件上运行 - 量化技术
近年来,大型语言模型(LLMs)的能力有了飞跃式的发展,使其在越来越多的应用场景中更加友好和适用。然而,随着LLMs的智能和复杂度的增加,其参数数量,即权重和激活值的数量也在增加,这意…...
shell printf详解
默认的 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。 1. printf命令语法组成: printg format-string [arguments] 第一部分为格式化字符串,该字符串最好用引号括起来 第二部分为参数列表,例如字符串或变量值的列表,该列表需…...

【数据分析】用Python做事件抽取任务-快速上手方案
目录 方法一:使用OmniEvent库安装OmniEvent使用OmniEvent进行事件抽取OmniEvent优点缺点 方法二:使用大模型使用GPT网页版进行事件抽取事件类型列表 大模型优点缺点 总结 在自然语言处理(NLP)领域,事件抽取是一项关键任…...

B端系统门门清之:HRM,人力资源系统,公司发展的源动力。
人才是公司发展的源动力,针对公司复杂人力的管理就是HRM系统的核心功能,本文就带领大家详细认识一下HRM系统,分别从什么是HRM系统,作用、功能模块、颜值提升四个方面来阐述。欢迎大家点赞评论收藏转发。 一、什么是HRM系统 HRM系…...

tplink安防监控raw文件转码合成mp4的方法
Tplink(深圳普联)专业的网络设备生产商,属于安防监控市场的后来者。Tplink的安防产品恢复了很多,其嵌入式文件系统也一直迭代更新。今天要说的案例比较特殊,其不仅仅要求恢复,还要求能解析出音频并且要求画面和声音实现“同步”。…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...