有時(shí)候我們需要限制一個(gè)api或頁面訪問的頻率,例如單ip或單用戶一分鐘之內(nèi)只能訪問多少次,類似這樣的需求很容易用redis來實(shí)現(xiàn)。那么redis如何限制IP訪問次數(shù)呢?下面跟著小編一起來看看吧。
目前創(chuàng)新互聯(lián)建站已為上千余家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、成都網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計(jì)、常山網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
策略1:
在redis中保存一個(gè)count值(int),key為user:$ip,value為該ip訪問的次數(shù),第一次設(shè)置key的時(shí)候,設(shè)置expires。
count加1之前,判斷是否key是否存在,不存在的話,有兩種情況:1、該ip未訪問過;2、該ip訪問過,但是key已經(jīng)過期了。那么此時(shí)需要再次設(shè)置一次expires。
如果用戶訪問的時(shí)候,判斷count的值是否大于上限,如果低于上限,就處理請(qǐng)求,否則就拒絕處理請(qǐng)求。
策略2:
考慮這種情況,假設(shè)只允許用戶60秒內(nèi)訪問100次,如果有一個(gè)用戶在第1秒訪問了1次,在第59秒的時(shí)候,訪問了99次,然后在第61秒的時(shí)候,訪問了100次。
如果按照策略1的情況處理,第1~60秒之間接受了100次,在第61秒接收100次請(qǐng)求,所以62~120這段時(shí)間內(nèi),不再處理該ip的請(qǐng)求。
貌似沒問題,但是,細(xì)細(xì)思考一下,第59秒到61秒之間接受了99+100=199請(qǐng)求,時(shí)間間隔只有3秒。那么這樣的話,最初的設(shè)計(jì)就存在問題了。
解決方案:可以使用redis的list(雙向隊(duì)列)數(shù)據(jù)結(jié)構(gòu),key就是user:$ip,也就是每一個(gè)ip設(shè)置一個(gè)雙向隊(duì)列,每次請(qǐng)求到達(dá)的時(shí)候,進(jìn)行如下判斷:
1、如果list中的元素個(gè)數(shù)少于100個(gè),那么就將請(qǐng)求到達(dá)時(shí)的時(shí)間戳Lpush到list中。
2、如果list中的元素多余100個(gè),那么,就取出Lindex(-1)即最右邊,也就是100個(gè)請(qǐng)求中最早的那一個(gè)請(qǐng)求的時(shí)間戳,如果最早的時(shí)間戳和當(dāng)前時(shí)間戳相差超過60秒,那么表示第一個(gè)請(qǐng)求已經(jīng)過期了,就將第一個(gè)請(qǐng)求出隊(duì)Rpop。然后將當(dāng)前時(shí)間戳入隊(duì)Lpush。
以上就是redis如何限制IP訪問次數(shù)的簡(jiǎn)略介紹,當(dāng)然詳細(xì)使用上面的不同還得要大家自己使用過才領(lǐng)會(huì)。如果想了解更多,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道哦!