IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 业务场景系列:更新Redis中设置过期时间Key的值 -> 正文阅读

[大数据]业务场景系列:更新Redis中设置过期时间Key的值

1.需求分析

在编写一个插入数据的接口,这个接口是对接前端的的,前端的功能大致就是用户浏览和留言,因为这个页面是无登录的,只要是使用者都可以提交这个数据,这个接口是公开的,为了避免有恶意的数据提交请求导致大量的脏数据保存,造成程序卡顿甚至宕机,对这个接口进行优化改造。

2.初级构思

在用户发送请求时,传过来的同时有HttpServletRequest,从这个里面可以获取用户的IP地址,利用Redis可以设置过期Key的方式,以ration加上用户IP为key,插入的value为可以提交数据的次数,然后设置过期时间。

redisService.set("rate:" + userIp,50,10,TimeUnit.MINUTES);

这句代码的意思是设置一个过期时间为10分钟的键值对,这样每次插入的时候,先查询一下value,如果这个key不存在的时候就set一次设置key的过期时间,如果value大于0的时候可以继续插入,插入的同时给key设置一个原值减一的值。如果value小于等于0的时候,就不能继续插入,返回一个提示。

if (rate>0){
	customerService.save(entity);
    redisService.set("rate:" + userIp,(rate-1));
} else if (rate<=0){
   return R.error().data("msg","提交次数超过限制,请勿重复提交!");
}
 

表面看这样没毛病,当时间到了,这个key就不存在了,程序便会新set一个过期时间为10分钟的key。但程序经过测试之后,数据的大量插入任然可以,用循环100次进行数据插入,结果都是success。这样结果不没有达到效果的。

在这里插入图片描述

3.原因分析

在经过Debug断点后发现,在每次插入之后对key重新set的操作,就相当于覆盖原有键值对,连同过期时间也覆盖掉,这样新set的键值对是没有过期时间的,另外在插入之前也没有新获取rate的值,导致rate的值一直不变,这样就产生了两个bug,key一直不会过期,数据也能无限次插入。

4.升级构思

在CSDN翻了半天发现没有一种很直观的方法,不过在经过60000毫秒的思考之后,发现可以另外再设置一个键值对,key为time加上用户的ip地址,value值为当前时间毫秒值加上过期时间毫秒值,就能算出key过期的时间了。代码设计如下:

Integer rate = getRate("rate:" + userIp,userIp);
if (rate==null){
	 redisService.set("rate:" + userIp,50);
     redisService.set("time:"+userIp,System.currentTimeMillis()+GlobalConstant.TEN_MINUTES);
    }

这样的设计之外我们要封装一个新的get key的方法:

private Integer getRate(String key, String userIp){
        Long expires = redisService.get("time:" + userIp);
        if (expires==null){
            return null;
        }else {
            if (System.currentTimeMillis()>=expires){
                redisService.del("time:" + userIp);
                redisService.del(key);
                return null;
            }else {
                return redisService.get(key);
            }
        }
    }

在过期时间为空的时候,rate的值也一定为空,所以直接返回空,否则就要对比当前时间和过期时间,如果当前时间大于过期时间,说明这个rate的时间已经到了,就需要删除rate和expires,当两个都删除后同样返回空,如果当前时间小于过期时间,就说明rate还在有效时间内,这个时候就正常get值就行,将获取的value返回即可,判断逻辑依旧为rate小于或者等于0的时候不能进行数据的插入。
当rate为空的时候,就继续创建新的rate和time键值对。

插入十次数据

插入50次数据

利用Redis实现一个简单的提交请求限制。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:23:07  更:2022-04-27 11:25:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:31:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码