Redis爬坑记(一):incr命令和expire命令的误区

article/2025/9/26 9:47:43
关注公众号

要实现的功能:限制用户的每分钟的访问次数一个有严重bug的代码:每次访问来了,就执行代码块二,当第一次访问,就走else语句,设置当前用户的次数为1,且设置该key的有效期是一分钟。
在一分钟之内,第二次来访问了,就走if语句了,因为redis存在这个key了,就实现自增一,然后取出来判断是否超过了设定的阈值。逻辑上看似看似没什么问题。代码块一:
Long maxAllowedTimes = 100L;
Long REQUEST_EXIT_MILLISECONDS = 60*1000L;

代码块二:

Jedis jedis = RedisUtils.getJedis();
String requestKey = Times + ":" + ID + ":" + getId();
if (jedis.exists(requestKey)) {//???jedis.incr(requestKey);String times = jedis.get(requestKey);if (StringUtil.strIsNotEmpty(times)){if (Long.parseLong(times) > maxAllowedTimes) {jedis.del(requestKey);return true;}}
} else {jedis.set(requestKey, "1");jedis.pexpire(requestKey,REQUEST_EXIT_MILLISECONDS);
}

实际上问题来了,maxAllowedTimes给设置成1000次,而实际上每分钟没有超过1000次的去访问数也能return true。
这TM设置的key的有效期没起到作用啊。。。各种讲道理讲不通,也是醉了。。。

其实不然,经过查资料发现:

Redis Incr 命令将 key 中储存的数字值增一,如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作,且将key的有效时间设置为长期有效。

耶,这么说就对了。其实,即使判断了key是否存在if (jedis.exists(requestKey)),也不能保证在执行jedis.incr(requestKey)自增的时候key是存在的。问题就出在这里。

就是这么巧,当三个问号“//???”这里时,恰好key到期了,从redis中删除了,然后继续执行jedis.incr(requestKey)自增,这时候,key的value等于1,且key是长期有效的。
所以当前用户不管何时每次访问的时候(只要redis不重启),key始终是存在的,这样就会一直自增,自增,自增到1000次。就这样bug就出现了。
 

解决方案:得对症下药啊

Jedis jedis = RedisUtils.getJedis();
String requestKey = Times + ":" + ID + ":" + getId();
jedis.incr(requestKey);//如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作,且将key的有效时间设置为长期有效.
String times = jedis.get(requestKey);
if("1".equals(times)){jedis.pexpire(requestKey,REQUEST_EXIT_MILLISECONDS);//如果是第一次访问,设置key的有效时间
} else if(StringUtils.isEmpty(times)){//如果key过期了,再incr(从第1次开始记录),再设置key的有效时间jedis.incr(requestKey);jedis.pexpire(requestKey,REQUEST_EXIT_MILLISECONDS);times = jedis.get(requestKey);
}
if (times != null && Long.parseLong(times) > maxAllowedTimes) {jedis.del(requestKey);return true;
}

至此,问题解决。
这里只是给出了一种“限制用户的每分钟的访问次数”的实现方案,应该还有其他更安全跟有效的实现方案。如有,请赐教,一起学习讨论。

 

另外:

Redis Incrby 命令将 key 中储存的数字加上指定的增量值,如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。

Redis Hincrby 命令用于为哈希表中的字段值加上指定增量值。

温馨提示:使用上面代码有坑,详细请细看下面大神们的讨论!

友情链接:
redis实现访问频次限制的几种方式


http://chatgpt.dhexx.cn/article/C3uMB30Y.shtml

相关文章

Redis INCR命令

路人甲:嘿,兄弟,知不知道redis的incr命令怎么用? 路人丙:啥?你这都不知道,不就是将key值增1嘛? 路人甲:可以一直一直一直加吗? 路人丙:…… 下图是…

《Redis系列第三篇、incr与decr使用|CSDN创作打卡》

incr与decr的效率要高于set操作,故而个人在开发过程中用作高并发的时候的限制器,效果非常nice的。 接下来看看具体用法与官方解释啊。 incr自增将存储的key数字加一 使用方法 incr testNum incr testNum incr testNum incr testNum incr testNum incr …

incr、incrby、decr、decrby命令的作用和用法

redis中incr、incrby、decr、decrby属于string数据结构,它们是原子性递增或递减操作。 incr递增1并返回递增后的结果;incrby根据指定值做递增或递减操作并返回递增或递减后的结果(incrby递增或递减取决于传入值的正负);decr递减1并返回递减后的结果&…

Redis:字符串INCR、INCRBY、INCRBYFLOAT、DECR、DECRBY命令介绍

INCR INCR key可用版本: > 1.0.0 时间复杂度: O(1)为键key对应的数字字符串(整数)加上一。 演示 如果键key不存在, 那么它的值会先被初始化为 0 , 然后再执行INCR命令。 INCR命令会返回键key对应的数…

利用Redis原子计数器incr实现计数器及接口限流

一、INCR命令介绍 Redis Incr 命令将 key 中储存的数字值增一。 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。且将key的有效时间设置为长期有效 。 如果值包含错误的类型,或字符串类型的值不能表示为数字&#x…

后渗透——内网转发之利用EarthWorm与proxifier搭建正向代理服务器

EarthWorm是一款用于开启 SOCKS v5 代理服务的工具,基于标准 C 开发,可提供多平台间的转接通讯,用于复杂网络环境下的数据转发。 Proxifier是一款功能非常强大的socks5客户端,可以让不支持通过代理服务器工作的网络程序能通过HTTP…

红蓝对抗之隧道技术第二篇(reGeorg内网穿透、SSH隧道本地Socks代理、SSH远程转发、Earthworm Socks5代理、Tunna正向代理、ICMP隧道、DNS隧道、Frp穿透)

文章目录 隧道应用reGeorg内网穿透SSH本地转发(正向)场景一场景二 SSH远程转发(反向)Earthworm Socks5代理正向代理反向代理 Tunna正向代理ICMP隧道DNS隧道Frp穿透推荐阅读&工具包 隧道应用 在进行内网渗透时,由于外网主机无法直接连接内网主机,所以…

earthworm四步走(解决拨入VPN后使用burp无法抓包的问题)

一、earthworm下载路径:https://github.com/idlefire/ew 二|、解压文件 三、执行命令:ew_for_Win.exe -s ssocksd -l 8888 四、设置burp上游代理

渗透测试之反弹代理(socks代理) (Earthworm工具) (windows和linux中的代理)

反弹代理 内网渗透不光只是反弹一个shell,反弹一个端口,我们更需要对内网进行更深一步的扫描和渗透,这时候就需要设置找到一个代理服务器,充当外网和内网数据转发的节点。 所以出现了反弹代理,也叫反弹socket。 使用…

NOIP 2016 提高组 复赛 第二天 第二题 蚯蚓 earthworm AC代码(单调队列)+15分代码(排序)+35分代码(堆 大顶堆 优先队列)+85分代码(更改堆中元素)

NOIP 2016 提高组 复赛 第二天 第二题 蚯蚓 earthworm AC代码(单调队列)15分代码(排序)35分代码(堆 大顶堆 优先队列)85分代码(更改堆中元素) 总目录详见:NOIP 提高组 复赛 试题 目录 信奥 历年 在线测评地址:https://www.luogu.com.cn/problem/P…

后渗透——内网转发之利用EarthWorm与proxifier搭建反向代理服务器

EarthWorm是一款用于开启 SOCKS v5 代理服务的工具,基于标准 C 开发,可提供多平台间的转接通讯,用于复杂网络环境下的数据转发。 Proxifier是一款功能非常强大的socks5客户端,可以让不支持通过代理服务器工作的网络程序能通过HTTP…

【教程】使用Earthworm (EW) 做Socks5代理完成内网穿透

EW 是一套便携式的网络穿透工具,具有 SOCKS v5服务架设和端口转发两大核心功能,可在复杂网络环境下完成网络穿透。 考虑到该工具影响很坏,该工具永久停止更新。 介绍: 示意图: 该工具能够以“正向”、“反向”、“…

内网穿透大杀器--EarthWorm

0x00 前言如果感觉本文对你有帮助,请在文章末尾点个赞,谢谢表哥们支持! 当你在内网渗透,并且拿下一台机器的权限时,你是不是觉得已经算是一次完整的渗透了? 不来一次内网漫游,渗透是不完整的&am…

EW(EarthWorm) 反向 socks5 代理

今天本想对学校的内网服务器进行人生中第一次横向渗透,奈何情况不允许,但好歹学习了一些东西,总要写下来保存 工具: EW: https://github.com/idlefire/ew proxychains: https://github.com/rofl0r/proxychains-ng 小米随身wifi…

使用Earthworm (EW) 做Socks5代理

正向代理 1.选择合适的ew文件(将文件ew_…改为ew.exe,为了在命令行少敲几个字母),上传到边缘服务器 2.边缘服务器输入 ew.exe -s ssocksd -l 8000 3.可借助proxifier工具配置攻击机整台机器的代理(proxifier添加代理服务器,ip为边…

EarthWorm结合proxifier的使用学习

拿下一个目标机器的web权限后,如何在本机就可以通过这台被拿下webshell的机器访问内网的其他主机的端口服务呢? 拿下一个shell后,想要访问这个shell主机的其他内网机器的服务,可以用earthworm作为一个流量转发,把ew对应…

内网渗透-Earthworm的简单使用(内网穿透工具)

Earthworm的简单介绍(一) 文章目录 EarthWorm下载地址1. 普通网络 1.1 跳板机存在公网IP 1.1.1 网络环境1.1.2 使用方法1.1.3 流量走向 1.2 跳板机不存在公网IP,可出网 1.2.1 网络环境1.2.2 使用方法1.2.3 流量走向 2. 二级网络 2.1 一级跳…

基于EarthWorm的正反向socks5代理

EarthWorm EarthWorm(ew)是一套便携式的网络穿透工具,具有 SOCKS v5服务架设和端口转发两大核心功能,能够以“正向”、“反向”、“多级级联”等方式打通一条网络隧道,直达网络深处,可在复杂网络环境下完成…

earthworm系列-earthworm介绍

earthworm的官方网站:http://www.earthwormcentral.org 1 Earthworm 简介 Earthworm 项目始于1993 年,主要目的是为了解决美国地震区域台网出现的问题。当时,区域内的地震台网存在的主要问题有:观测设备陈旧,…