服务限流算法:从令人头疼到信手拈来

前言

随着系统规模的扩大和用户量的增加,服务限流成为了一个非常重要的话题。一方面,系统需要能够处理大量的请求,不至于因为负载过高而崩溃;另一方面,又需要避免恶意攻击或者其他异常情况对系统造成影响。本文将介绍一些常见的服务限流算法,包括漏桶算法、令牌桶算法、计数器算法等,并提供Java实现示例,帮助读者更好地理解这些算法。

漏桶算法

算法原理

漏桶算法是一种最简单的限流算法。它的基本思想是,将请求看作是水流,服务则是下面的水桶。当请求进来时,先放到容量固定的漏桶中,然后以一定的速度流出。如果漏桶已经满了,那么新的请求就会被丢弃。这个速度可以是固定的,也可以是动态的,与具体实现有关。

漏桶算法可以有效平滑流量,控制请求处理的速度。

Java实现

public class LeakyBucket {private final int capacity; // 漏桶容量private final int ratePerSecond; // 水流出的速度(每秒)private int waterLevel = 0; // 桶中当前水位private long lastUpdateTime = System.currentTimeMillis(); // 上次更新时间public LeakyBucket(int capacity, int ratePerSecond) {this.capacity = capacity;this.ratePerSecond = ratePerSecond;}public synchronized boolean allowRequest() {// 计算时间差,更新漏桶中的水量long timePassed = System.currentTimeMillis() - lastUpdateTime;int waterDrained = (int) (timePassed / 1000 * ratePerSecond);waterLevel = Math.max(0, waterLevel - waterDrained);lastUpdateTime = System.currentTimeMillis();// 判断漏桶中的水量是否超过容量,如果超过则拒绝请求if (waterLevel >= capacity) {return false;} else {waterLevel++;return true;}}
}

漏桶算法的Java实现非常简单,只需要记录漏桶的容量和速度,并在处理请求时更新漏桶中的水位即可。在上述示例中,使用synchronized关键字确保线程安全。

令牌桶算法

算法原理

令牌桶算法也是一种常见的限流算法。它的基本思想是,系统以一定的速度生成令牌并放入桶中,请求需要从桶中取出令牌才能被处理。如果桶中没有令牌,则请求不能被处理。这个速度可以是固定的,也可以是动态的,与具体实现有关。

令牌桶算法可以控制请求处理的速率,同时还可以应对短时间内的请求突发。

Java实现

public class TokenBucket {private final int capacity; // 令牌桶容量private final int ratePerSecond; // 令牌生成速度(每秒)private int tokenCount = 0; // 桶中当前令牌数private long lastUpdateTime = System.currentTimeMillis(); // 上次更新时间public TokenBucket(int capacity, int ratePerSecond) {this.capacity = capacity;this.ratePerSecond = ratePerSecond;}public synchronized boolean allowRequest() {// 计算时间差,更新桶中的令牌数long timePassed = System.currentTimeMillis() - lastUpdateTime;int tokensToAdd = (int) (timePassed / 1000 * ratePerSecond);tokenCount = Math.min(capacity, tokenCount + tokensToAdd);lastUpdateTime = System.currentTimeMillis();// 判断令牌数是否足够,如果足够则允许请求if (tokenCount > 0) {tokenCount--;return true;} else {return false;}}
}

令牌桶算法的Java实现与漏桶算法类似,只需要记录令牌桶的容量和速度,并在处理请求时更新桶中的令牌数即可。在上述示例中,使用synchronized关键字确保线程安全。

计数器算法

算法原理

计数器算法是一种基于时间窗口的限流算法。它的基本思想是,用一个定长的时间窗口来统计请求次数,当请求次数超过阈值时,则拒绝新的请求。这个时间窗口可以是固定的,也可以是动态的,与具体实现有关。

Java实现

public class Counter {private final int maxRequests; // 时间窗口内最大请求数private final long timeWindowInMillis; // 时间窗口长度(毫秒)private final Queue<Long> requestTimes = new LinkedList<>(); // 请求时间队列public Counter(int maxRequests, long timeWindowInMillis) {this.maxRequests = maxRequests;this.timeWindowInMillis = timeWindowInMillis;}public synchronized boolean allowRequest() {// 移除过期的请求时间long currentTime = System.currentTimeMillis();while (!requestTimes.isEmpty() && requestTimes.peek() < currentTime - timeWindowInMillis) {requestTimes.poll();}// 判断请求数是否达到阈值if (requestTimes.size() < maxRequests) {requestTimes.offer(currentTime);return true;} else {return false;}}
}

计数器算法的Java实现需要使用一个队列来存储请求时间,并在处理请求时动态地移除过期的请求时间。在上述示例中,使用synchronized关键字确保线程安全。

总结

本文介绍了三种常见的服务限流算法,漏桶算法、令牌桶算法和计数器算法,以及它们在Java中的实现。这些算法在实际应用中都有自己的优缺点,大家可以根据具体需求选择合适的算法。同时,也可以结合多种算法,形成更加严谨、可靠的限流策略。

👉 💐🌸 公众号请关注 "果酱桑", 一起学习,一起进步! 🌸💐

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

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

相关文章

pip安装python包到指定python版本下

python -m pip install 包名1.命令行进入到指定python安装目录。比如我电脑上有python3.8也有python3.9。准备给python3.9安装指定的包

3.OpenFeign的使用

OpenFeign 文章目录 OpenFeign一. 什么是OpenFeign二. OpenFeign基础使用1.添加依赖2.配置Nacos配置信息3.在项目中开启OpenFeign4.编写OpenFeign调用代码5.调用OpenFeign接口 三. OpenFeign内置的超时重试机制1.配置超时重试2.覆盖Retryer对象 四.自定义超时重试机制1.自定义超…

技术分享| anyRTC之RTN网络

RTN(Real-time Network)中文名&#xff1a;实时音视频传输网络。 RTN是最近几年由各大RTC的云厂商提出的一个全新架构的音视频实时传输网络概念。类似于直播的CDN网络&#xff0c;RTN是对音视频的实时性又强烈要求的场景而设计的&#xff0c;原理上全球端到端的时延通过RTN网络…

JSP EL表达式获取list/Map集合与java Bean对象

上文 JSP EL表达式基本使用 中 我们对EL表达式做了一个基本的了解 也做了基础的字符串数据使用 那么 我们可以来看一下我们的集合 首先 list 这个比较简单 我们直接这样写代码 <% page import"java.util.ArrayList" %> <% page import"java.util.Lis…

基于C#实现优先队列

一、堆结构 1.1性质 堆是一种很松散的序结构树&#xff0c;只保存了父节点和孩子节点的大小关系&#xff0c;并不规定左右孩子的大小&#xff0c;不像排序树那样严格&#xff0c;又因为堆是一种完全二叉树&#xff0c;设节点为 i,则 i/2 是 i 的父节点&#xff0c;2i 是 i 的…

信息系统的安全保护等级的五个级别

信息系统的安全保护等级分为五级&#xff1a;第一级为自主保护级、第二级为指导保护级、第三级为监督保护级、第四级为强制保护级、第五级为专控保护级。 法律依据&#xff1a;《信息安全等级保护管理办法》第四条 信息系统的安全保护等级分为以下五级&#xff1a;   &#…

【C语言】计算实时太阳角度(高度角、方位角),以及使用stm32单片机实时获取时间戳

整体计算方法 在编写该代码的过程中寻找了多篇博文和论文&#xff0c;综合所有文章且按网上的以0时的方位角的0&#xff0c;且随时间累加累加至360度。我修改了博文和论文的一些角度的计算方法。得到一下代码与网站计算的方位角相互验证过&#xff0c;误差不超过1 验证网站 太…

LoRaWAN 中国地区文件详细解读

目录 一、LoRaWAN简介 二、CN470-510地区参数分析 1.信道频率 2.支持功率 3.支持空速 4.最大负载大小 5.接受窗口参数 三、CN470_510默认参数 Lora LoraWAN教程 一、LoRaWAN简介 LoraWAN是一种基于LoRa远距离通信技术配套设计的一套通讯协议和系统架构。LoRaWAN网络通…

Java实现拼图游戏

1、了解拼图游戏基本功能&#xff1a; 拼图游戏内容由若干小图像块组成的&#xff0c;通过鼠标点击图像块上下左右移动&#xff0c;完成图像的拼凑。 2、拼图游戏交互界面设计与开发&#xff1a; 通过创建窗体类、菜单、中间面板和左右面板完成设计拼图的交互界面 &#xff…

外贸自建站服务器怎么选?网站搭建的工具?

外贸自建站服务器用哪个好&#xff1f;如何选海洋建站的服务器&#xff1f; 外贸自建站是企业拓展海外市场的重要手段之一。而在这个过程中&#xff0c;选择一个适合的服务器对于网站的稳定运行和优化至关重要。海洋建站将为您介绍如何选择适合的外贸自建站服务器。 外贸自建…

【STM32外设系列】GPS定位模块(ATGM336H)

&#x1f380; 文章作者&#xff1a;二土电子 &#x1f338; 关注公众号获取更多资料&#xff01; &#x1f438; 期待大家一起学习交流&#xff01; 文章目录 一、GPS模块简介二、使用方法2.1 引脚介绍2.2 数据帧介绍2.3 关于不同的启动方式 三、前置知识3.1 strstr函数3.2…

基于H1ve一分钟搭好CTF靶场

写在前面 ◉ ‿ ◉ 上一篇文章给大家详细介绍了基于H1ve搭建CTF靶场&#xff0c;以及过程中可能遇到的报错及解决方法&#xff0c;那么这篇文章&#xff0c;我总结了一下&#xff0c;将不会遇到报错的方法给到大家&#xff0c;但是前提是你的服务器最好是一个全新的哦~~~ 我…

C++基础从0到1入门编程(四)类和对象

系统学习C 方便自己日后复习&#xff0c;错误的地方希望积极指正 往期文章&#xff1a; C基础从0到1入门编程&#xff08;一&#xff09; C基础从0到1入门编程&#xff08;二&#xff09; C基础从0到1入门编程&#xff08;三&#xff09; 参考视频&#xff1a; 1.黑马程序员匠心…

香蕉派BPI-M4 Zero单板计算机采用全志H618,板载2GRAM内存

Banana Pi BPI-M4 Zero 香蕉派 BPI-M4 Zero是BPI-M2 Zero的最新升级版本。它在性能上有很大的提高。主控芯片升级为全志科技H618 四核A53, CPU主频提升25%。内存升级为2G LPDDR4&#xff0c;板载8G eMMC存储。它支持5G WiFi 和蓝牙, USB接口也升级为type-C。 它具有与树莓派 …

23. 深度学习 - 多维向量自动求导

Hi, 你好。我是茶桁。 前面几节课中&#xff0c;我们从最初的理解神经网络&#xff0c;到讲解函数&#xff0c;多层神经网络&#xff0c;拓朴排序以及自动求导。 可以说&#xff0c;最难的部分已经过去了&#xff0c;这节课到了我们来收尾的阶段&#xff0c;没错&#xff0c;生…

算法通关村第十二关-白银挑战字符串经典题目

大家好我是苏麟 , 今天带来字符串相关的题目 . 大纲 反转问题字符串反转K个一组反转仅仅反转字母反转字符串中的单词 反转问题 字符串反转 描述 : 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s的形式给出。 题目 : LeetCode 344. 反转…

webshell之扩展免杀

由于很多企业为了防止源码泄露&#xff0c;都会使用加密扩展将代码进行加密&#xff0c;那么我们就可以就将计就计&#xff0c;将webshell也利用扩展加密&#xff0c;将特征消除&#xff0c;从而达到免杀的效果 1.php-beast 扩展地址 下载dll&#xff0c;并添加至ext中 在php…

MySQL中自增id用完怎么办?

MySQL中自增id用完怎么办&#xff1f; MySQL里有很多自增的id&#xff0c;每个自增id都是定义了初始值&#xff0c;然后不停地往上加步长。虽然自然数是没有上限的&#xff0c;但是在计算机里&#xff0c;只要定义了表示这个数的字节长度&#xff0c;那它就有上限。比如&#…

python数据结构与算法-15_堆与堆排序

堆(heap) 前面我们讲了两种使用分治和递归解决排序问题的归并排序和快速排序&#xff0c;中间又穿插了一把树和二叉树&#xff0c; 本章我们开始介绍另一种有用的数据结构堆(heap)&#xff0c; 以及借助堆来实现的堆排序&#xff0c;相比前两种排序算法要稍难实现一些。 最后我…

Linux开发工具(含gdb调试教程)

文章目录 Linux开发工具&#xff08;含gdb调试教程&#xff09;1、Linux 软件包管理器 yum2、Linux开发工具2.1、Linux编辑器 -- vim的使用2.1.1、vim的基本概念2.1.2、vim的基本操作2.1.3、vim正常模式命令集2.1.4、vim末行模式命令集 2.2、vim简单配置 3、Linux编译器 -- gcc…