俗话说得好,缓存,限流和降级是系统的三把利剑。刚好项目中每天早上导出数据时因调订单接口频率过高,订单系统担心会对用户侧的使用造成影响,让我们对调用限速一下,所以就正好用上了。
常用的限流算法有2种:漏桶算法和令牌桶算法。
漏桶算法
漏桶算法:请求先进入“桶”中,然后桶以一定的速率处理请求。如果请求的速率过快会导致桶溢出。根据描述可以知道,漏桶算法会强制限制请求处理的速度。任你请求的再快还是再慢,我都是以这种速率来处理。
但是对于很多情况下,除了要求能够限制平均处理速度外,还要求能允许一定程度的的突发情况。这样的话,漏桶算法就不合适了,用令牌桶算法更合适。
令牌桶算法
令牌桶算法的原理是:系统以恒定的速率往桶里丢一定数量的令牌,请求只有拿到了令牌才能处理。当桶里没有令牌时便可拒绝服务。
Guava中的Ratelimiter便是实现的令牌桶算法,同时能支持一定程度的突发请求。
private static RateLimiter one=RateLimiter.create(2);//每秒2个
private static RateLimiter two=RateLimiter.create(2);//每秒2个
private RateLimitUtil(){};
public static void acquire(RateLimiter r,int num){
double time =r.acquire(num);
System.out.println("wait time="+time);
}
public static void main(String[] args) throws InterruptedException {
acquire(one,1);
acquire(one,1);
acquire(one,1);
System.out.println("-----");
acquire(two,10);
acquire(two,1);
}
输出结果:
wait time=0.0
wait time=0.499163
wait time=0.489308
-----
wait time=0.0
wait time=4.497819
可以看到,我们以每秒2个请求的速度生成令牌。对one来说