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

服务器雪崩的应对策略之----限流

限流是一种控制流量的技术,旨在防止系统在高并发请求下被压垮。通过限流,可以确保系统在负载高峰期依然能保持稳定运行。常见的限流策略包括令牌桶算法、漏桶算法、计数器算法和滑动窗口算法。

常见的限流方法

  • 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;
}

结论

限流方法可以有效地保护系统免受过载的影响,确保系统在高并发情况下仍能稳定运行。通过选择适合的限流策略,可以根据不同场景和需求实现精确的流量控制。

相关文章:

服务器雪崩的应对策略之----限流

限流是一种控制流量的技术&#xff0c;旨在防止系统在高并发请求下被压垮。通过限流&#xff0c;可以确保系统在负载高峰期依然能保持稳定运行。常见的限流策略包括令牌桶算法、漏桶算法、计数器算法和滑动窗口算法。 常见的限流方法 1. 令牌桶算法 (Token Bucket Algorithm)2…...

Python12 列表推导式

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

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&#xff0c;可以根据这个信息查询显卡型号 查询网址&#xff1a;https://admin.pci-ids.ucw.cz/mods/PC/10de?actionhelp?helppci 输入后点击Jump查询 我们发现显卡型号为RTX …...

二叉树的这五种遍历方法你们都会了吗?

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

使用模数转换器的比例电阻测量基础知识

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

(C++语言的设计和演化) C++的设计理念

文章目录 前言&#x1f4d6;C 语言设计规则&#x1f4d0;规则和原理&#x1f4d0;一般性规则&#x1f4d0;设计支持规则&#x1f4d0;语言的技术性规则&#x1f4d0;低级程序设计支持规则 &#x1f4d6;标准化&#xff08;扩充评判准则&#xff09;&#x1f4d0;它精确吗&#…...

AI音乐:创新引擎还是创意终结者?

✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点赞、关注、收藏、评论&#xff0c;是对我最大…...

20240621每日后端---------如何优化项目中的10000个if-else 语句?

如何优化 10000 个 if-else 语句&#xff1f;有没有好的解决方案&#xff1f; 额&#xff0c;本身问题就很奇怪&#xff0c;怎么可能有这种代码。。。世界你让我陌生&#xff0c;但是我们还是假象着看看能不能解决一下。 解决方案1&#xff1a;策略模式 使用策略模式确实可以…...

【STM32】时钟树系统

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

docker换源

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

百度在线分销商城小程序源码系统 分销+会员组+新用户福利 前后端分离 带完整的安装代码包以及搭建部署教程

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

Flutter【组件】富文本组件

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

中国恋爱交友相亲软件有哪些?大型婚恋相亲交友APP真实测评推荐

嘿嘿&#xff0c;当了29年的单身汪&#xff0c;这下总算不再单着啦&#xff01;这两年把身边能找的人都找遍了&#xff0c;也没碰到合适的。没办法&#xff0c;就跑到网上去试试&#xff0c;坚持了有半年&#xff0c;可算有对象啦&#xff01;下面给大家说说我用过的几个能脱单…...

快速欧氏聚类与普通欧氏聚类比较

1、前言 文献《FEC: Fast Euclidean Clustering for Point Cloud Segmentation》介绍了一种快速欧氏聚类方法,大概原理可以参考如下图,具体原理可以参考参考文献。 2、时间效率比较:快速欧氏聚类VS普通欧氏聚类 网上搜集的快速欧式聚类,与自己手写的普通欧式聚类进行对比,…...

如何让大语言模型在规格普通的硬件上运行 - 量化技术

近年来&#xff0c;大型语言模型&#xff08;LLMs&#xff09;的能力有了飞跃式的发展&#xff0c;使其在越来越多的应用场景中更加友好和适用。然而&#xff0c;随着LLMs的智能和复杂度的增加&#xff0c;其参数数量&#xff0c;即权重和激活值的数量也在增加&#xff0c;这意…...

shell printf详解

默认的 printf 不会像 echo 自动添加换行符&#xff0c;我们可以手动添加 \n。 1. printf命令语法组成&#xff1a; printg format-string [arguments] 第一部分为格式化字符串&#xff0c;该字符串最好用引号括起来 第二部分为参数列表,例如字符串或变量值的列表,该列表需…...

【数据分析】用Python做事件抽取任务-快速上手方案

目录 方法一&#xff1a;使用OmniEvent库安装OmniEvent使用OmniEvent进行事件抽取OmniEvent优点缺点 方法二&#xff1a;使用大模型使用GPT网页版进行事件抽取事件类型列表 大模型优点缺点 总结 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;事件抽取是一项关键任…...

B端系统门门清之:HRM,人力资源系统,公司发展的源动力。

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

tplink安防监控raw文件转码合成mp4的方法

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

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...