发生过载的原因主要是缓冲区满,导致处理的请求超时。所以限制流量,尽早拒绝过载状态的请求,能够保证服务尽量处理负载过程中的请求。
限流的主要方法有下面四种:
本篇介绍计数器算法。
计数器算法是在一定的时间间隔里,记录请求次数,当请求次数超过该时间限制时,就把计数器清零,然后重新计算。当请求次数超过间隔内的最大次数时,拒绝访问。
例如:一个接口每分钟允许访问100次。实现方式如下:
1 设置一个计数器 count ,接收一个请求就将计数器加一,同时记录当前时间。
2 判断当前时间和上次统计时间是否为同一分钟。
如果是,则判断 count 是否超过阈值,如果超过阈值,则返回限流拒绝。
如果不是,则吧 count 重置为1,判断是否超过阈值。
如下图所示,该计数器算法要求每分钟请求的阈值不超过100个。
package currentLimit;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
/**
* @className: CounterLimit
* @description: 计数器算法
* @date: 2022/1/8
* @author: cakin
*/
public class CounterLimit {
// 记录上次统计时间
static Date lastDate = new Date();
// 初始化值
static int counter = 0;
/**
* 功能描述:模拟一次请求是否限流
*
* @return true:限流 false;不限流
* @author cakin
* @date 2022/1/8
* @description:
*/
static boolean countLimit() {
// 获取当前时间
Date now = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
// 当前分
int minute = calendar.get(Calendar.MINUTE);
calendar.setTime(lastDate);
int lastMinute = calendar.get(Calendar.MINUTE);
if (minute != lastMinute) {
lastDate = now;
counter = 0;
}
++counter;
return counter >= 100; // 判断计数器是否大于每分钟限定的值。
}
// 测试方法
public static void main(String[] args) {
for (; ; ) {
// 模拟一秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Random random = new Random();
int i = random.nextInt(3);
// 模拟1秒内请求1次
if (i == 1) {
if (countLimit()) {
System.out.println("限流了" + counter);
} else {
System.out.println("没限流" + counter);
}
} else if (i == 2) { // 模拟1秒内请求2次
for (int j = 0; j < 2; j++) {
if (countLimit()) {
System.out.println("限流了" + counter);
} else {
System.out.println("没限流" + counter);
}
}
} else { // 模拟1秒内请求10次
for (int j = 0; j < 10; j++) {
if (countLimit()) {
System.out.println("限流了" + counter);
} else {
System.out.println("没限流" + counter);
}
}
}
}
}
}
这种方法实现简单,但有一个明显的缺点,那就是在两个间隔之间,如果有密集的请求。则会导致单位时间内的实际请求超过阈值。
当在时间临界点的时候(比如 0:59时刻),瞬间来了 100 个请求,这时能够正常处理请求,然后在1:01时刻的时候,又来了100个请求,这时也能够正常处理这些请求。但在 2s 内,一共处理 200 个请求,可能会造成后端过载。
该算法实现简单,如果两个峰值出现在计数器清零点附近,则会造成在短时间的时间间隔类超过阈值的现象,可能导致后端过载。如下图所示,第一分钟和第二分钟的交界处分别来了100个请求,此时不会限流,灰色部分时间跨度内的请求量会让后端过载。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/122385943
内容来源于网络,如有侵权,请联系作者删除!