一種基於Redis的10行代碼實現IP頻率控制方法

優勢:可支持海量訪問的頻率控制,只須要增長Redis機器,單個Redis節點(只佔用一個cpu core)便可支持10萬/s以上的處理。
git

基於IP頻率限制是種常見需求,基於Redis能夠十分簡單實現對IP的頻率限制,具體手段爲利用Redis的key過時和原子加減兩個特性。github

以IP做爲key,頻率爲key過時時長,好比限制單個IP在2秒內頻率爲100,則key過時時長爲2秒,基於 r3c(a Redis Cluster C++ Client)的實現大體以下:
r3c::CRedisClient redis("127.0.0.1:6379,127.0.0.1:6380");
int ret = redis.incrby(ip, 1);
if (ret > 1000) // 超過頻率
{    
}
else // 訪問放行
{    
    if (1 == ret)
        redis.expire(ip, 2); // 頻率控制爲2秒內1000次訪問        
}

完整示例:
redis

// https://github.com/eyjian/r3c
#include <r3c/r3c.h>

int main()
{
    std::string ip = "127.0.0.1";
    r3c::CRedisClient redis("10.223.25.102:6379");
    r3c::set_debug_log_write(NULL);
    for (int i=0; i<100000; ++i)
    {
// r3c基於redis的EVAL命令提供了一個帶過時參數的incrby,
        // 這樣避免了兩次操做的非原子時expire調用可能不成功問題。
        int ret = redis.incrby(ip, 1);
        if (ret > 1000) // 限制單個IP每2秒最多訪問1000次
        {
            printf("[OVER] 超過頻率,限制訪問\n");
        }
        else
        {
            if (1 == ret)
            {
                redis.expire(ip, 2); // 頻率設定爲2秒
                printf("[FIRST] 第一次,訪問放行\n");
            }
            else
            {
                printf("[OK] 訪問放行\n");
            }
        }
    }
    redis.del(ip);
    return 0;
}
相關文章
相關標籤/搜索