com.ghp.request.limiter.impl.FixedWindowCountLimiter Maven / Gradle / Ivy
package com.ghp.request.limiter.impl;
import com.ghp.request.annotation.RequestLimit;
import com.ghp.request.limiter.Limiter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author ghp
* @title 固定窗口计数限流器
* @description
*/
public class FixedWindowCountLimiter implements Limiter {
/**
* 记录上一次请求时漏桶的容量
* 如果初始容量为 10,表示一个桶最多同时处理10个请求,超出部分就会被限流
* key是接口名,value是接口的当前窗口内的请求数量
*/
private Map countMap = new ConcurrentHashMap<>();
/**
* 记录接口的上一次请求起始时间
* key是接口名,value是上一次请求的时间戳
*/
private Map timestampMap = new ConcurrentHashMap<>();
/**
* 限流
*
* @param methodName
* @param requestLimitAnnotation
* @return true-发生限流 false-未限流
*/
@Override
public boolean limit(String methodName, RequestLimit requestLimitAnnotation) {
int qps = requestLimitAnnotation.qps();
long interval = requestLimitAnnotation.interval();
long now = System.currentTimeMillis();
// 窗口中当前的请求数量
int count = countMap.getOrDefault(methodName, 0);
// 上一次请求的时间戳(不存在时,则以当前时间为起始)
long preTimestamp = timestampMap.computeIfAbsent(methodName, key -> now);
// 判断当前请求是否在当前时间窗口
if (now > preTimestamp + interval) {
// 当前请求不在当前时间窗口,直接开启新窗口,并且重置请求次数
countMap.put(methodName, 0);
timestampMap.put(methodName, now);
return false;
}
// 当前请求在当前时间窗口,判断是否超过请求阈值
if (qps < (count + 1)) {
// 超过阈值,限流
return true;
}
// 未超过阈值,更新窗口中的请求数
countMap.put(methodName, count + 1);
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy