当前位置: 首页 > 后端技术 > Java

面试官:限流算法有哪些?

时间:2023-04-01 15:56:49 Java

限流算法有很多种,但是常见的限流算法有3种:计数器算法、漏桶算法和令牌桶算法。1.计数器算法计数器算法是记录一定时间间隔内的请求次数。当请求次数超过时间限制时,计数器被清零,然后重新计算。当请求数超过间隔内的最大数时拒绝访问。计数器算法的实现比较简单,但存在“尖峰现象”。秒杀现象是指,比如限流QPS(每秒查询率)为100,算法的实现思路是从第一个请求开始计时,每请求一次计数加1接下来的1秒,如果累计达到100个,后面的所有请求都会被拒绝。1秒结束后,将计数重置为0并重新开始计数。如果在单位时间1秒的前10毫秒内处理了100个请求,那么在接下来的990毫秒内将拒绝所有请求。我们称这种现象为“尖峰现象”。计数器算法的简单实现代码如下:importjava.util.Calendar;importjava.util.Date;importjava.util.Random;publicclassCounterLimit{//记录上次统计的时间staticDatelastDate=newDate();//初始化值staticintcounter=0;//限流方法staticbooleancountLimit(){//获取当前时间Datenow=newDate();日历calendar=Calendar.getInstance();日历.setTime(现在);//当前分钟intminute=calendar.get(Calendar.MINUTE);日历.setTime(lastDate);intlastMinute=calendar.get(Calendar.MINUTE);如果(分钟!=lastMinute){lastDate=现在;计数器=0;}++计数器;返回计数器>=100;//判断计数器是否大于每分钟的限制值。}//测试方法publicstaticvoidmain(String[]args){for(;;){//模拟一秒try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}随机random=newRandom();inti=random.nextInt(3);//1秒内模拟1次请求if(i==1){if(countLimit()){System.out.println("limitflow"+counter);}else{System.out.println("无限流量"+counter);}}elseif(i==2){//1秒内模拟2次请求for(intj=0;j<2;j++){if(countLimit()){System.out.println("Limited"+柜台);}else{System.out.println("Unlimited"+counter);}}}else{//1秒内模拟10次请求for(intj=0;j<10;j++){if(countLimit()){System.out.println("有限"+计数器);}else{System.out.println("无限制"+counter);}}}}}}2。漏桶算法。它以固定的速率和恒定的速度流出。当流入量过大(超过桶的容量)时,多余的水流(请求)直接溢出如下图:系统。例如Sentinel中的trafficshaping(统一排队功能)就是通过该算法实现的,如下图所示:更多Sentinel内容见:https://mp.weixin.qq。com/s/nF5f18BP8hscqIEmIFRN8Q3。令牌桶算法令牌以固定的速率放入令牌桶中,桶中最多存储N个令牌(Token)。当桶满时,新添加的令牌将被丢弃或拒绝。当请求到达时,从桶中删除1个令牌。令牌桶中的令牌既可以取出,也可以添加。因此,为了保证数据可以随时通过接口,必须不断地向桶中添加令牌。可以看出,向桶中添加令牌的速度决定了数据通过接口的速度。我们通过控制令牌添加到令牌桶的速率来控制接口上的流量。令牌桶的实现原理如下图所示:4.漏桶算法VS令牌桶算法漏桶算法以恒定固定的速率流出请求,传入请求的速率是任意的。当传入请求的数量累积到漏桶的容量时,新的传入请求将被拒绝。令牌桶算法以固定的速率向桶中添加令牌。是否处理请求取决于桶中是否有足够的令牌。当令牌数量减少到零时,新请求将被拒绝。令牌桶算法允许突发请求,只要有令牌就可以处理,允许一定程度的突发流量。漏桶算法限制恒定流出率,从而平滑突发流入率。比如当服务器空闲时,理论上漏桶算法服务器可以直接处理一个洪峰(一个洪流过程的最大流量),但是漏桶算法处理请求的速率是恒定的。因此,前期的服务器资源只能根据恒定的漏水率逐级处理请求,不能直接处理这种泛洪。令牌桶算法不存在这个问题,因为它可以一次性填满令牌桶,处理完一个洪峰后再限流。总结起来,常见的限流算法有3种:计数器算法:实现简单,但存在尖峰现象;漏桶算法:以固定速率处理请求,更平滑地处理任意流量,并且可以实现流量整形;令牌桶算法:控制桶中的令牌实现限流,可以处理一定的突发流量,比如处理一个洪峰。参考&致谢《分布式微服务架构》https://blog.csdn.net/chengqi...本文已收录到Gitee开源仓库《Java 面试突击》,里面包含:Redis、JVM、并发、并发、MySQL、Spring、SpringMVC、SpringBoot、SpringCloud、MyBatis、设计模式、消息队列等SpringModules。Java面试够用了:最全Java面试题库(2023版),持续更新中...