Redis應用之[限制訪問頻率]

  咱們知道當網站的訪問量忽然很大的時候確定會對服務器形成影響,甚至沒法訪問,若是是正常的訪問那麼很好說明業務量增大能夠考慮系統的擴展,可是若是是搜索引擎爬蟲頻繁訪問或是一些惡意訪問,那這時候咱們就應該限制這些訪問的訪問次數。redis恰好能夠解決這個問題java

Redis實現限制訪問頻率

1.實現訪問一

  限制每一個用戶每分鐘最多隻能訪問100個頁面。實現思路:key使用有"rate.limiting:IP",value使用數值,用戶每次訪問將value的值經過INCR命令自增1.若是自增後的值是1同時設置過時時間爲1分鐘。這樣用戶每次訪問的時候都讀取該鍵的值,若是超過了100就代表該用戶的訪問頻率超過了限制,須要提示用戶稍後訪問。且該鍵每分鐘會自動被刪除。因此下一分鐘又會從新計算,也就達到了限制訪問頻率的目的。
在這裏插入圖片描述redis

代碼邏輯:算法

String key = "rage.limiting:"+ip;
// 判斷key是否存在
int flag = exists(key);// key rate.limiting:192.168.88.60
if(flag == 1){
    // key 存在 自增1
    int count = incr(key);
    if(count > 100){
        // 超過限制
        log.info("訪問頻率超過了限制,請稍後重試");
        return ;
    }
}else{
    // key 不存在 
    multi(); // 開啓事務
    incr(key); // key不存在自增1 值爲1
    expire(key,60); // 設置過時時間
    exec(); // 提交事務
}

2.實現方式二

  實現方式一其實還有個問題,好比若是用戶第一分鐘的訪問了99次,前面58秒訪問了9次,後面1秒訪問了90次,而後用戶後一秒也訪問了99次,然後一分鐘的第一秒訪問了90次,後面的58秒訪問了9次,這樣按照上面的算法是沒有問題的,可是這種極端狀況你們仍是能夠發現問題的。
在這裏插入圖片描述服務器

  解決方法:先將上面案例中的100次調整爲10次便於在次場景中描述,要精確的保證同一個用戶每分鐘最多訪問10次,須要記錄下來用戶每次訪問的時間。所以對每一個用戶咱們使用一個List列表類型的鍵來記錄他最近10次訪問的時間,一旦鍵中的元素超過10個,就判斷最先的元素距離如今的時間是否小於1分鐘。若是是表示用戶最近1分鐘訪問次數超過了10次,若是不是就將如今的時間加入到隊列中,同時把最先的元素刪除。
在這裏插入圖片描述網站

在這裏插入圖片描述

邏輯代碼搜索引擎

String key = "rate.limiting:"+IP;
int listLength = llen(key);
if(listLength < 10){
    lpush(key,new());
}else{
    long time = lindex(key,-1);
    if(now()-time < 60){
        log.info("訪問頻率超過了限制,請稍後再試");
    }else{
        lpush(key,now);
        ltrim(key,0,9);
    }
}
相關文章
相關標籤/搜索