优点:可支持海量访问的频率控制,只需要增加Redis机器,单个Redis节点(只占用一个cpu core)即可支持10万/s以上的处理。
基于IP频率限制是种常见需求,基于Redis可以十分简单实现对IP的频率限制,具体手段为利用Redis的key过期和原子加减两个特性。
以IP作为key,频率为key过期时长,比如限制单个IP在2秒内频率为100,则key过期时长为2秒,基于(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次访问
-
}
完整示例:
-
// 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;
-
}
阅读(951) | 评论(0) | 转发(0) |