Redis 實(shí)現(xiàn)限流的三種方式
往期熱門文章:
2、一次 QPS 翻倍的 Java 服務(wù)性能優(yōu)化
第一種:基于Redis的setnx的操作
第二種:基于Redis的數(shù)據(jù)結(jié)構(gòu)zset
代碼如下
public Response limitFlow(){
Long currentTime = new Date().getTime();
System.out.println(currentTime);
if(redisTemplate.hasKey("limit")) {
Integer count = redisTemplate.opsForZSet().rangeByScore("limit", currentTime - intervalTime, currentTime).size(); // intervalTime是限流的時(shí)間
System.out.println(count);
if (count != null && count > 5) {
return Response.ok("每分鐘最多只能訪問(wèn)5次");
}
}
redisTemplate.opsForZSet().add("limit",UUID.randomUUID().toString(),currentTime);
return Response.ok("訪問(wèn)成功");
}通過(guò)上述代碼可以做到滑動(dòng)窗口的效果,并且能保證每N秒內(nèi)至多M個(gè)請(qǐng)求,缺點(diǎn)就是zset的數(shù)據(jù)結(jié)構(gòu)會(huì)越來(lái)越大。實(shí)現(xiàn)方式相對(duì)也是比較簡(jiǎn)單的。
第三種:基于Redis的令牌桶算法
提到限流就不得不提到令牌桶算法了。
令牌桶算法提及到輸入速率和輸出速率,當(dāng)輸出速率大于輸入速率,那么就是超出流量限制了。
也就是說(shuō)我們每訪問(wèn)一次請(qǐng)求的時(shí)候,可以從Redis中獲取一個(gè)令牌,如果拿到令牌了,那就說(shuō)明沒(méi)超出限制,而如果拿不到,則結(jié)果相反。
依靠上述的思想,我們可以結(jié)合Redis的List數(shù)據(jù)結(jié)構(gòu)很輕易的做到這樣的代碼,只是簡(jiǎn)單實(shí)現(xiàn)
依靠List的leftPop來(lái)獲取令牌
// 輸出令牌
public Response limitFlow2(Long id){
Object result = redisTemplate.opsForList().leftPop("limit_list");
if(result == null){
return Response.ok("當(dāng)前令牌桶中無(wú)令牌");
}
return Response.ok(articleDescription2);
}再依靠Java的定時(shí)任務(wù),定時(shí)往List中rightPush令牌,當(dāng)然令牌也需要唯一性,所以我這里還是用UUID進(jìn)行了生成
// 10S的速率往令牌桶中添加UUID,只為保證唯一性
@Scheduled(fixedDelay = 10_000,initialDelay = 0)
public void setIntervalTimeTask(){
redisTemplate.opsForList().rightPush("limit_list",UUID.randomUUID().toString());
}
最近熱文閱讀:
1、推薦 15 款常用開(kāi)發(fā)工具 2、一次 QPS 翻倍的 Java 服務(wù)性能優(yōu)化 3、Maven 劃分模塊最佳實(shí)踐 4、面試官問(wèn):select......for update會(huì)鎖表還是鎖行? 5、Spring Boot + GraphQL 才是 API 的未來(lái)! 6、一個(gè)基于 SpringBoot2+redis+Vue 的商城管理系統(tǒng),拼團(tuán)、砍價(jià)、秒殺等都有,可二次開(kāi)發(fā)接私活! 7、用 MySQL 實(shí)現(xiàn)分布式鎖,你聽(tīng)過(guò)嗎? 8、全員遠(yuǎn)程辦公,半年入 1 億美元:GitHub 的最大競(jìng)爭(zhēng)對(duì)手上市了! 9、面試官:Spring AOP、AspectJ、CGLIB 都是什么鬼?它們有什么關(guān)系? 10、10 個(gè) VSCode 超級(jí)摸魚神器,確定不試一下? 關(guān)注公眾號(hào),你想要的Java都在這里
評(píng)論
圖片
表情
