Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6086387
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: C/C++

2016-09-29 03:22:39

优点:可支持海量访问的频率控制,只需要增加Redis机器,单个Redis节点(只占用一个cpu core)即可支持10万/s以上的处理。
基于IP频率限制是种常见需求,基于Redis可以十分简单实现对IP的频率限制,具体手段为利用Redis的key过期和原子加减两个特性。
以IP作为key,频率为key过期时长,比如限制单个IP在2秒内频率为100,则key过期时长为2秒,基于(a Redis Cluster C++ Client)的实现大致如下:

  1. r3c::CRedisClient redis("127.0.0.1:6379,127.0.0.1:6380");
  2. int ret = redis.incrby(ip, 1);
  3. if (ret > 1000) // 超过频率
  4. {
  5. }
  6. else // 访问放行
  7. {
  8.     if (1 == ret)
  9.         redis.expire(ip, 2); // 频率控制为2秒内1000次访问
  10. }

完整示例:

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

  3. int main()
  4. {
  5.     std::string ip = "127.0.0.1";
  6.     r3c::CRedisClient redis("10.223.25.102:6379");
  7.     r3c::set_debug_log_write(NULL);
  8.     for (int i=0; i<100000; ++i)
  9.     {
  10.         // r3c基于redis的EVAL命令提供了一个带过期参数的incrby,
            // 这样避免了两次操作的非原子时expire调用可能不成功问题。
  11.         int ret = redis.incrby(ip, 1);
  12.         if (ret > 1000) // 限制单个IP每2秒最多访问1000次
  13.         {
  14.             printf("[OVER] 超过频率,限制访问\n");
  15.         }
  16.         else
  17.         {
  18.             if (1 == ret)
  19.             {
  20.                 redis.expire(ip, 2); // 频率设定为2秒
  21.                 printf("[FIRST] 第一次,访问放行\n");
  22.             }
  23.             else
  24.             {
  25.                 printf("[OK] 访问放行\n");
  26.             }
  27.         }
  28.     }
  29.     redis.del(ip);
  30.     return 0;
  31. }



阅读(914) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~