基于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());
}
綜上枢贿,代碼實(shí)現(xiàn)起始都不是很難,針對(duì)這些限流方式我們可以在AOP或者filter中加入以上代碼刀脏,用來(lái)做到接口的限流局荚,最終保護(hù)你的網(wǎng)站。