常见的限流
创始人
2025-05-28 07:51:35
0

限流的主要用途

限流的主要用途是保护系统,防止因为高并发请求而导致系统崩溃、过载或响应变慢等问题。
通过限制单位时间内的请求量,可以有效地控制系统的负载,提高系统的稳定性和可靠性。

限流的另一个重要作用是保障服务质量,尤其是对于一些对实时性要求较高的服务,如在线游戏、金融交易等,限流可以确保每个请求都能够得到及时的响应,避免因为某些请求的卡顿、延迟等影响其他请求的处理效率。

除此之外,限流还可以防止恶意攻击,如DDoS攻击等,限制恶意请求的数量以及频率,从而保护系统安全。

常见算法

常见的限流算法包括计数器算法、令牌桶算法和漏桶算法。

  1. 计数器算法

计数器算法是通过计数器统计单位时间内请求次数,当请求次数超过阈值时,返回错误信息。Java实现代码如下:

public class CounterLimiter {private final int limit; //限流阈值private int count = 0; //计数器private long start = System.currentTimeMillis(); //起始时间public CounterLimiter(int limit) {this.limit = limit;}public synchronized boolean tryAcquire() {long now = System.currentTimeMillis();if (now < start + 1000) { //一秒内请求次数未达到限流阈值if (++count > limit) { //请求次数超过限流阈值return false;}} else { //一秒已过,重置计数器和起始时间count = 1;start = now;}return true;}
}
  1. 令牌桶算法

令牌桶算法是将请求放入令牌桶中,每个请求需要取走一个令牌才能被处理,当令牌桶中无可用令牌时,返回错误信息。Java实现代码如下:

public class TokenBucketLimiter {private final int capacity; //令牌桶容量private final double rate; //令牌发放速率private double tokenCount = 0; //当前令牌数量private long lastTime = System.nanoTime(); //上次令牌发放时间public TokenBucketLimiter(int capacity, double rate) {this.capacity = capacity;this.rate = rate;}public synchronized boolean tryAcquire() {long now = System.nanoTime();double tokensToAdd = (now - lastTime) * rate / 1e9; //根据时间间隔计算新增令牌数量tokenCount = Math.min(capacity, tokenCount + tokensToAdd); //更新令牌数量lastTime = now;if (tokenCount > 0) { //当前有可用令牌tokenCount--;return true;} else { //当前无可用令牌return false;}}
}
  1. 漏桶算法

漏桶算法是通过设置一个固定容量的漏桶,请求先进入漏桶中,然后以固定速率出漏桶,当漏桶满了时,新加入的请求会被丢弃。Java实现代码如下:

public class LeakyBucketLimiter {private final int capacity; //漏桶容量private final double rate; //漏桶流出速率private double waterLevel = 0; //漏桶当前水位private long lastTime = System.nanoTime(); //上次漏桶流出时间public LeakyBucketLimiter(int capacity, double rate) {this.capacity = capacity;this.rate = rate;}public synchronized boolean tryAcquire() {long now = System.nanoTime();waterLevel -= (now - lastTime) * rate / 1e9; //根据时间间隔计算漏桶流出的水量waterLevel = Math.max(0, waterLevel); //水位不能小于0lastTime = now;if (waterLevel < capacity) { //漏桶未满waterLevel++;return true;} else { //漏桶已满return false;}}
}

注意事项

  1. 合理设置阈值:要根据系统的实际情况和承受能力来设置限流阈值,太低可能无法满足业务需求,太高可能会导致系统性能下降或崩溃。
  2. 细粒度控制:应该根据不同业务逻辑和接口进行细粒度的限流控制,避免对整个系统造成影响。
  3. 良好的反馈机制:要及时反馈限流信息给客户端,告知客户端请求被限流,并提示如何解决问题。同时,也要记录并统计限流数据,监控系统运行状况。
  4. 动态调整阈值:在高峰期或特殊情况下,可以动态调整限流阈值,提高系统的灵活性和适应性。
  5. 综合考虑:限流只是保障系统稳定和安全的一种手段,应该与其他手段(如负载均衡、缓存等)结合使用,综合考虑系统的整体性能和安全性。

最佳实践建议

  1. 设定合理的阈值:在实际应用中,需要根据业务特点、系统资源等因素来设定合理的阈值,并不断优化。
  2. 选择合适的限流算法:常见的限流算法有漏桶算法和令牌桶算法,使用时需要根据实际情况进行选择。
  3. 细分限流策略:可以根据具体业务场景细分不同的限流策略,例如对用户、IP、接口等进行限流。
  4. 监控与告警:对于被限流的请求需要进行监控,并及时发出告警,以便后续进行问题排查和调整。
  5. 异常处理:当系统出现异常时,需要及时停止对其它请求的响应,并进行相应的限流处理,避免造成更严重的影响。
  6. 不断优化:限流策略需要不断优化,结合实际情况进行调整,以达到更好的效果。

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...