基于redis的限流
/**
* 基于redis的限流
* @author: whh
* @date: 2020.03.19
**/
public class RedisRateLimitUtil {
public static final Logger LOGGER = LoggerFactory.getLogger(RedisRateLimitUtil.class); @Resource(name = "anticheatRedisClient") private RedisClient anticheatRedisClient; public boolean tryAcquire(String key, int timeWindow, int limitNum) { boolean acquireResult = anticheatRedisClient.execute(key, new JedisAction<Boolean>() { @Override public Boolean action(Jedis jedis) { try { String setNxResult = jedis.set(key, "1", "NX", "EX", timeWindow); if ("OK".equals(setNxResult)) { return true; } Long num = jedis.incr(key); if (num == 1) { jedis.expire(key, timeWindow); } if (num > limitNum) { return false; } return true; } catch (Exception e) { LOGGER.error("acquireResult error", e); } return true; } }); return acquireResult; } }
常用的限流算法有哪些?
1、计数器固定窗口算法
没到阈值,接受请求,计数器+1,超过时间窗口,计数器设为0重新开始计数。
缺点:存在突刺现象,不够平滑。
2、滑动窗口算法
一个时间窗口划分成多个时间窗口,当请求时间大于窗口最大时间,向前平移,丢弃第一个窗口数据,第二个窗口变为第一个,在最后新增一个窗口。
3、漏斗算法
将所有请求放到一个大桶里,由桶匀速处理。
请求量过大超过桶大小,会被丢弃,限制访问速度可保护自身系统。
4、令牌桶算法
先匀速生成令牌,放入桶中,请求来了取令牌,取到则执行。
限制平均速度的情况下可以允许一定程度的流量突发。
向上吧,少年