如何利用 Redis 实现接口频次限制

介绍:

我们可以利用 redis 过期Key来实现接口的频次限制。可以自定义一些访问的(速度)限制条件来把那些触发限制的请求拒之门外.一般常用来进行对爬虫的限制.

下面就利用 redis 来实现了一个简单的案例:

装饰器实现

def frequency_limit(f):
  @wraps(f)
  def frequency_function(*args, **kwargs):
    if 'csrf_token' in session:
      token = session.get("csrf_token")
      url_ = request.url_rule
      redis_key = token + str(url_)
      conn = redis.StrictRedis(host="127.0.0.1", port="6379", password="123456", db=0)
      clicks = conn.get(redis_key)
      if not clicks:
        conn.set(redis_key, 1)
        conn.expire(redis_key, 60)
      else:
        if int(clicks) >= 5:
          return jsonify({'code': 500, 'status': 0, 'message': "您的访问频率太快,请稍后再试", 'data': [],
                  'token': token})
        overdue = 1 if conn.ttl(redis_key) <= 0 else conn.ttl(redis_key)
        conn.set(redis_key, int(clicks) + 1)
        conn.expire(redis_key, overdue)
    return f(*args, **kwargs)

  return frequency_function

注:在使用 redis Key过期的时候需要注意,在设置了过期时间后,再次改变 Key 的 Value 值时,之前设置的过期时间会失效。

解决办法:

1)在修改 Value 值的时候,查一下过期时间还有多少 ttl 在修改值的时候把过期时间重新赋值回去(本文用的就是此方法)

2)redis 中设置了过期时间,如果 list 结构中添加一个数据或者改变 hset 数据的一个字段是不会清除超时时间的;

官方网站看了一下expire的说明:
这样解释的:

The timeout will only be cleared by commands that delete or overwrite the contents of the key, including DEL, SET, GETSET and all the *STORE commands. This means that all the operations that conceptually alter the value stored at the key without replacing it with a new one will leave the timeout untouched. For instance, incrementing the value of a key with INCR, pushing a new value into a list with LPUSH, or altering the field value of a hash with HSET are all operations that will leave the timeout untouched.

如果用DEL, SET, GETSET会将key对应存储的值替换成新的,命令也会清除掉超时时间;如果list结构中添加一个数据或者改变hset数据的一个字段是不会清除超时时间的;如果想要通过set去覆盖值那就必须重新设置expire。

到此这篇关于如何利用 Redis 实现接口频次限制的文章就介绍到这了,更多相关Redis 实现接口频次限制内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++访问Redis的mset 二进制数据接口封装方案

    需求 C++中使用hiredis客户端接口访问redis: 需要使用mset一次设置多个二进制数据 以下给出三种封装实现方案: 简单拼接方案 在redis-cli中,mset的语法是这样的: 复制代码 代码如下: /opt/colin$./redis-cli mset a 11 b 22 c 333 OK 按照这样的语法拼接后,直接使用hiredis字符串接口redisCommand传递: void msetNotBinary(redisContext *c, const vector<stri

  • Springboot+redis+Interceptor+自定义annotation实现接口自动幂等

    前言: 在实际的开发项目中,一个对外暴露的接口往往会面临很多次请求,我们来解释一下幂等的概念:任意多次执行所产生的影响均与一次执行的影响相同.按照这个含义,最终的含义就是对数据库的影响只能是一次性的,不能重复处理.如何保证其幂等性,通常有以下手段: 1:数据库建立唯一性索引,可以保证最终插入数据库的只有一条数据 2:token机制,每次接口请求前先获取一个token,然后再下次请求的时候在请求的header体中加上这个token,后台进行验证,如果验证通过删除token,下次请求再次判断toke

  • SpringBoot下token短信验证登入登出权限操作(token存放redis,ali短信接口)

    SpringBoot下token短信验证登入登出(token存放redis) 不对SpringBoot进行介绍,具体的可以参考官方文档 介绍:token基本使用,redis基本使用 思路:获取短信(验证并限制发送次数,将code存放redis)-->登入(验证并限制错误次数,将用户信息及权限放token,token放redis)-->查询操作(略),主要将前两点,不足的希望指出,谢谢 步骤: 1.整合Redis需要的依赖,yml自行配置,ali短信接口依赖(使用引入外部包的方式) <de

  • spring boot+ redis 接口访问频率限制的实现

    生产环境下可以解决的问题: 1.短信验证码请求评率限制(防止抓包短信轰炸) 2.热点数据请求评率限制(防止数据库爆炸) @Component public class BlackInterceper implements HandlerInterceptor { @Autowired private RedisTemplate<String, Object> redisTemplate; private Logger log = LoggerFactory.getLogger(this.get

  • 如何利用 Redis 实现接口频次限制

    介绍: 我们可以利用 redis 过期Key来实现接口的频次限制.可以自定义一些访问的(速度)限制条件来把那些触发限制的请求拒之门外.一般常用来进行对爬虫的限制. 下面就利用 redis 来实现了一个简单的案例: 装饰器实现 def frequency_limit(f): @wraps(f) def frequency_function(*args, **kwargs): if 'csrf_token' in session: token = session.get("csrf_token&qu

  • Springboot利用Redis实现接口幂等性拦截

    目录 前言 正文 实战开始 核心三件套 工具类三件套 REDIS配置类 前言 近期一个老项目出现了接口幂等性 校验问题,前端加了按钮置灰, 依然被人拉着接口参数一顿输出,还是重复调用了接口,小陈及时赶到现场,通过复制粘贴,完成了后端接口幂等性调用校验. 以前写过一篇关于接口简单限流防止重复调用的,但是跟该篇还是不一样的,该篇的角度是接口和参数整体一致才当做重复. 简单限流:Springboot使用redis实现接口Api限流的实例 该篇内容: 实现接口调用的幂等性校验 方案 :自定义注解+red

  • Springboot使用redis实现接口Api限流的实例

    前言 该篇介绍的内容如题,就是利用redis实现接口的限流(  某时间范围内 最大的访问次数 ) . 正文 惯例,先看下我们的实战目录结构: 首先是pom.xml 核心依赖: <!--用于redis数据库连接--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId>

  • Springboot使用redis实现接口Api限流的示例代码

    前言 该篇介绍的内容如题,就是利用redis实现接口的限流(  某时间范围内 最大的访问次数 ) . 正文 惯例,先看下我们的实战目录结构: 首先是pom.xml 核心依赖: <!--用于redis数据库连接--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId>

  • 利用Redis实现防止接口重复提交功能

    目录 前言 1.自定义注解 2.自定义拦截器 3.Redis工具类 4.其他想说的 前言 在划水摸鱼之际,突然听到有的用户反映增加了多条一样的数据,这用户立马就不干了,让我们要马上修复,不然就要投诉我们. 这下鱼也摸不了了,只能去看看发生了什么事情.据用户反映,当时网络有点卡,所以多点了几次提交,最后发现出现了十几条一样的数据. 只能说现在的人都太心急了,连这几秒的时间都等不了,惯的.心里吐槽归吐槽,这问题还是要解决的,不然老板可不惯我. 其实想想就知道为啥会这样,在网络延迟的时候,用户多次点击

  • Java利用redis实现防止接口重复提交

    目录 一.摘要 二.方案实践 2.1.引入 redis 组件 2.2.添加 redis 环境配置 2.3.编写获取请求唯一ID的接口,同时将唯一ID存入redis 2.4.编写服务验证逻辑,通过 aop 代理方式实现 2.5.在相关的业务接口上,增加SubmitToken注解即可 三.小结 一.摘要 在上一篇文章中,我们详细的介绍了对于下单流量不算高的系统,可以通过请求唯一ID+数据表增加唯一索引约束这种方案来实现防止接口重复提交! 随着业务的快速增长,每一秒的下单请求次数,可能从几十上升到几百

  • Java利用Redis实现消息队列的示例代码

    本文介绍了Java利用Redis实现消息队列的示例代码,分享给大家,具体如下: 应用场景 为什么要用redis? 二进制存储.java序列化传输.IO连接数高.连接频繁 一.序列化 这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成java对象; 主要是用到了ByteArrayOutputStream和ByteArrayInputStream; 注意:每个需要序列化的对象都要实现Serializable接口; 其代码如下: package Utils

  • Spring Boot项目利用Redis实现集中式缓存实例

    在高并发请求的web服务架构中,随着数据量的提升,缓存机制为绝大多数的后台开发所使用.这篇文章主要介绍如何在Spring Boot项目中为Entity添加利用Redis实现的集中式缓存. 1. 利用Spring Initializr来新建一个spring boot项目 2. 在pom.xml中添加redis.mysql和cache等相关依赖.一般情况下,缓存一般是在大规模数据库存储下所需要的 <dependency> <groupId>org.springframework.boo

  • Java利用Redis实现高并发计数器的示例代码

    业务需求中经常有需要用到计数器的场景:譬如一个手机号一天限制发送5条短信.一个接口一分钟限制多少请求.一个接口一天限制调用多少次等等.使用Redis的Incr自增命令可以轻松实现以上需求.以一个接口一天限制调用次数为例: /** * 是否拒绝服务 * @return */ private boolean denialOfService(String userId){ long count=JedisUtil.setIncr(DateUtil.getDate()+"&"+user

  • springboot利用aop实现接口异步(进度条)的全过程

    目录 一.前言 二.时序图 三.功能演示 四.关键代码 Controller AsyncAop AsyncService 五.源码地址 总结 一.前言 在项目中发现有接口(excel导入数据)处理数据需要耗时比较长的时间,是因为数据量比较大,同时数据的校验需要耗费一定时间,决定使用一种通用的方法解决这个问题. 解决方案:通过aop使接口异步处理,前端轮询另外一个接口查询进度. 目标: 1接口上一个注解即可实现接口异步(优化:可以通过header参数动态控制是否异步) 2一个方法实现进度条的更新

随机推荐