java redis自增操作_【转载】关于spring boot使用redis的increment()方法自增问题
需求是限制IP频繁访问某接口,用的方案是使用redis记录访问IP的值,先设定好初始值,每次访问自增,达到某限定值后,进行阻止。
用的是自定义工具类,使用spring封装的spring-data-redis进行操作,在对某key进行increment()方法时,报错:
redis ERR value is not an integer or out of range
代码逻辑如下:
Integer count = (Integer) redisUtil.get(ipAddress);//取得key的value
if (count == null){
redisUtil.set(ipAddress,1,10);
return false;
}else if(count == 3){
return false;
}else {
redisUtil.incr(ipAddress,1);
return false;
}
第一次进来,如果没有redis中没有数据,则设置key,value和time,key是ip, value初始值为1,有效时长为10秒。
如果没达到限制次数,则对key自增1。
redisUtil.incr()方法实现如下:
@Resource
private RedisTemplate redisTemplate; //这里使用的是redisTemplate
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 递增
* @param key 键
// * @param by 要增加几(大于0)
* @return
*/
public long incr(String key, long delta){
if(delta<0){
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
开始以为是incr方法接受的参数是long型,但我传入的是INTEGER类型,但转换后还是没有解决问题,问题不是出在这,后来通过查找资料发现,Spring对Redis序列化的策略有两种,分别是StringRedisTemplate和RedisTemplate,其中StringRedisTemplate用于操作字符串,RedisTemplate使用的是JDK默认的二进制序列化。
大家都知道redis序列化是将key,value值先转换为流的形式,再存储到redis中。
RedisTemplate是使用的JdkSerializationRedisSerializer序列化,序列化后的值包含了对象信息,版本号,类信息等,是一串字符串,所以无法进行数值自增操作。
而StringRedisTemplate序列化策略是字符串的值直接转为字节数组,所以存储到redis中是数值,所以可以进行自增操作。
StringRedisSerializer源码:
public class StringRedisSerializer implements RedisSerializer {
private final Charset charset;
public StringRedisSerializer() {
this(StandardCharsets.UTF_8);
}
public StringRedisSerializer(Charset charset) {
Assert.notNull(charset, "Charset must not be null!");
this.charset = charset;
}
public String deserialize(@Nullable byte[] bytes) {
return bytes == null ? null : new String(bytes, this.charset);
}
public byte[] serialize(@Nullable String string) {
return string == null ? null : string.getBytes(this.charset); //注意这里是字节数组
}
}
所以问题出在这里,我们需要自定义序列化策略,在application启动类中添加如下:
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
//定义key序列化方式
//RedisSerializer redisSerializer = new StringRedisSerializer();//Long类型会出现异常信息;需要我们上面的自定义key生成策略,一般没必要
//定义value的序列化方式
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// template.setKeySerializer(redisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
费了2多小时才成功解决问题,RedisUtil.incr()能够成功对key进行自增了,如有错误之处请欢迎指出。
java redis自增操作_【转载】关于spring boot使用redis的increment()方法自增问题相关推荐
- Spring Boot整合Redis以及Redis的原理
Redis的原理及知识 Redis简介 redis是一个key-value.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...
- Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅)
Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅) 1. 配置环境 在SpringBoot2.0版本以后,原来使用的jedis被替换成为了let ...
- spring boot shiro redis整合基于角色和权限的安全管理-Java编程
一.概述 本博客主要讲解spring boot整合Apache的shiro框架,实现基于角色的安全访问控制或者基于权限的访问安全控制,其中还使用到分布式缓存redis进行用户认证信息的缓存,减少数据库 ...
- 大聪明教你学Java | Spring Boot 整合 Redis 实现访问量统计
前言 之前开发系统的时候客户提到了一个需求:需要统计某些页面的访问量,记得当时还纠结了一阵子,不知道怎么去实现这个功能,后来还是在大佬的带领下借助 Redis 实现了这个功能.今天又回想起了这件事,正 ...
- Linux 安装Redis-6.2.5,配置及使用(RDB与AOF持久化、sentinel机制、主从复制、Spring Boot 集成 Redis)
CentOS 7 安装Redis-6.2.5版本 Redis采用的是基于内存的单进程 单线程模型 的KV数据库,由C语言编写.官方提供的数据是可以达到100000+的qps 应用场景: 令牌(Toke ...
- Spring boot整合Redis(入门教程)
目录 源码分析 jedis VS lettuce 整合测试 导入依赖 配置连接 测试 存入字符串 存入对象 五大数据类型操作 自定义RedisConfig 存入对象 Redis工具类(常用API) 以 ...
- 猿创征文 | 微服务 Spring Boot 整合Redis 实战开发解决高并发数据缓存
文章目录 一.什么是 缓存? ⛅为什么用缓存? ⚡如何使用缓存 二.实现一个商家缓存 ⌛环境搭建 ♨️核心源码 ✅测试接口 三.采用 微服务 Spring Boot 注解开启缓存 ✂️@CacheEn ...
- Spring Boot与Redis的集成
1.在Linux中安装Redis. 1.1.在线下载软件 1.2.安装软件 1.3.修改配置文件 1.4.启动Redis: 2.添加Redis起步缓存,在pom.xml中添加Spring Boot支持 ...
- 玩转spring boot——结合redis
前言 Redis 是一个高性能的key-value数据库. redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用.它提供了 ...
- 深入理解 Redis Template及4种序列化方式__spring boot整合redis实现RedisTemplate三分钟快速入门
概述 使用Spring 提供的 Spring Data Redis 操作redis 必然要使用Spring提供的模板类 RedisTemplate, 今天我们好好的看看这个模板类 . RedisTem ...
最新文章
- Android性能优化常见问题,终局之战
- opencv python 图像去噪
- 累加出整个范围所有的数最少还需要几个数
- jieba是python中一个重要的标准函数库_python——Jieba库整理(基础知识+实例)
- 怎么来判断光端机产品的性能优劣?光端机的产品性能有哪些?
- 特征计算 - 遍历求值提速 6 万倍 lambda...if...else(if...else...) +map() 对比 iterrows() - Python代码
- 地表净辐射通量数据、太阳辐射量数据、降雨量数据、气温数据、日照时长、水汽压分布、风速风向数据、地表温度
- gson下载java_gson.jar
- 为什么说全球变暖不是阴谋论
- 【Html】 Html写静态淘宝页面
- uniapp uniCloud 云开发上传图片与查看图片
- 百钱百鸡问题最优解法
- i5 6600 HD530联想扬天S5250黑苹果
- eclipse中import existing projects into workspace和open projects from file systems分别有什么用?
- 按汉字首字母排序(sql语句) 只为收集,本人复制粘贴水寒冰局的
- DB2重启数据库实例
- FSF 公布 2022 年自由软件获奖名单
- ensemble learning 学习分享:回归问题
- 锂离子电池性能测试软件,锂电池性能测试检测方法有哪些
- 哈工大csapp lab3
热门文章
- HashMap,HashTable,ConcurrentHashMap面试总结!!!
- Linux之文档与目录结构
- 《memory leak: stackwalk》
- 安装php时,configure: error: xml2-config not found. Please check your libxml2 installation
- C++ 中的类型限定符 类型限定符提供了变量的额外信息。
- Microsoft Edge浏览器最新版已经换成开源Chromium引擎了,附官方下载地址
- 人脸识别领域相关金融标准将出台
- 从人工“智障”到人工智能,AI交互还缺什么?
- 机器学习中数据处理与可视化的python、numpy等常用函数
- 大学毕业后八大让你加班成狗专业盘点,你的专业上榜了嘛?