redis实现计数--------Redis increment
经理提出新的需求,需要知道每天微信推送了多少条模板消息,成功多少条,失败多少条,想到用Redis缓存,网上查了一些资料,Redis中有方法increment,测试代码如下
Controller
import javax.annotation.Resource; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; /**
* @author wangqq
* @version 创建时间:2018年8月10日 下午2:30:47
* 类说明
*/
@Controller
@RequestMapping("test")
public class TestController { @Resource
private TestService testService; @RequestMapping("testRedis")
@ResponseBody
public int testRedis (){
return testService.testRedis ();
}
}
Service
import javax.annotation.Resource; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service; /**
* @author wangqq
* @version 创建时间:2018年8月10日 下午2:32:13
* 类说明
*/
@Service
public class TestService { @Resource
RedisTemplate<String,Object> redisTemplate; @Resource(name="redisTemplate")
private ValueOperations<String,Object> ops; public int testRedis() {
try {
//此方法会先检查key是否存在,存在+1,不存在先初始化,再+1
ops.increment("success", 1); return (int) ops.get("success");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} return 0 ;
} }
直接使用ops.get("success"),会出现错误,报错信息 Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.EOFException。 根据信息,可以看到是反序列化出错,上网查一下,貌似是因为JDK序列化之后,反序列化失败。解决办法:
第一种解决办法
用 redisTemplate.boundValueOps("success").get(0, -1)获得key值
import javax.annotation.Resource; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service; /**
* @author wangqq
* @version 创建时间:2018年8月10日 下午2:32:13
* 类说明
*/
@Service
public class TestService { @Resource
RedisTemplate<String,Object> redisTemplate; @Resource(name="redisTemplate")
private ValueOperations<String,Object> ops; public int testRedis() {
try {
//此方法会先检查key是否存在,存在+1,不存在先初始化,再+1
ops.increment("success", 1); //return (int) ops.get("success"); return Integer.valueOf(redisTemplate.boundValueOps("success").get(0, -1));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} return 0 ;
} }
页面显示为2,因为第一次已经成功了,只是get失败了

第二种解决办法
添加一个方法 getKey
import javax.annotation.Resource; import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service; /**
* @author wangqq
* @version 创建时间:2018年8月10日 下午2:32:13
* 类说明
*/
@Service
public class TestService { @Resource
RedisTemplate<String,Object> redisTemplate; @Resource(name="redisTemplate")
private ValueOperations<String,Object> ops; public int testRedis() {
try {
//此方法会先检查key是否存在,存在+1,不存在先初始化,再+1
ops.increment("success", 1); //return (int) ops.get("success"); //return Integer.valueOf(redisTemplate.boundValueOps("success").get(0, -1)); return (int) getKey("success");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} return 0 ;
} public long getKey(final String key) { return redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer(); byte[] rowkey = redisSerializer.serialize(key);
byte[] rowval = connection.get(rowkey); try {
String val = redisSerializer.deserialize(rowval);
return Long.parseLong(val);
} catch (Exception e) {
return 0L;
}
}
});
} }
页面返回

最后一步,设置每天零点过期,重新计数
//当天时间
Date date = new Date();
//当天零点
date = DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
//第二天零点
date = DateUtils.addDays(date, +1); redisTemplate.expireAt("success", date);
redis实现计数--------Redis increment的更多相关文章
- 华为云PB级数据库GaussDB(for Redis)揭秘第八期:用高斯 Redis 进行计数
摘要:高斯Redis,计数的最佳选择! 一.背景 当我们打开手机刷微博时,就要开始和各种各样的计数器打交道了.我们注册一个帐号后,微博就会给我们记录一组数据:关注数.粉丝数.动态数-:我们刷帖时,关注 ...
- Redis作者谈Redis应用场景(转)
add by zhj : 这是Redis的作者antirez在他的技术博客中写的一篇文章 英文原文:take-advantage-of-redis-adding-it-to-your-stack 译文 ...
- 高可用Redis(七):Redis持久化
1.什么是持久化 持久化就是将数据从掉电易失的内存同步到能够永久存储的设备上的过程 2.Redis为什么需要持久化 redis将数据保存在内存中,一旦Redis服务器被关闭,或者运行Redis服务的主 ...
- Redis 基础:Redis 数据类型
Redis 数据类型 Redis支持五种数据类型:string(字符串).hash(哈希).list(列表).set(集合)及zset(sorted set:有序集合). String(字符串) st ...
- Redis之配置文件redis.conf
解读下 redis.conf 配置文件中常用的配置项,为不显得过于臃长,已选择性删除原配置文件中部分注释. # Redis must be started with the file path as ...
- Redis(3) 配置文件 redis.conf
Redis.conf 配置详解: # Redis configuration file example. # # Note that in order to read the configuratio ...
- 分布式数据存储 之 Redis(一) —— 初识Redis
分布式数据存储 之 Redis(一) -- 初识Redis 为什么要学习并运用Redis?Redis有什么好处?我们步入Redis的海洋,初识Redis. 一.Redis是什么 Redis 是一个 ...
- redis基础及redis特殊场景使用描述
数据类型 String set list hash zset redis原理 单线程:redis是单线程+io多路复用:检查文件描述的就绪状态 对比memchached:多线程+锁 redis优势 解 ...
- Redis 实战 —— 14. Redis 的 Lua 脚本编程
简介 Redis 从 2.6 版本开始引入使用 Lua 编程语言进行的服务器端脚本编程功能,这个功能可以让用户直接在 Redis 内部执行各种操作,从而达到简化代码并提高性能的作用. P248 在不编 ...
随机推荐
- 获取 PHPstorm编辑器 注册码地址
网址: http://idea.lanyus.com/ 注册码有效期为2016年11月24日至2017年11月23日使用前请将“0.0.0.0 account.jetbrains.com”添加到hos ...
- Vim入门基础知识集锦
1. 简介 Vim(Vi[Improved])编辑器是功能强大的跨平台文本文件编辑工具,继承自Unix系统的Vi编辑器,支持Linux/Mac OS X/Windows系统,利用它可以建立.修 ...
- 利用node、express初始化项目
前端做整站是开发,例如:前端是用了vue创建初始化项目,后端我们不会php.java等,我们只能用node去创建去做后端代码,本文就给大家讲解最基础的从零开始创建一个项目的后端环境. 一般来说前后端代 ...
- vue-router同路由地址切换无效解决
本来还想写的,一搜就有现成的,算了: http://blog.csdn.net/peng_guan/article/details/59702699
- marquee标签弹幕效果
播放个视频的时候看到很有趣的弹幕,想着前端能不能做个弹幕效果.弹幕是滚动的,所以首先想到了<marquee>标签.但事实上,<marquee>标签不是w3c的标准,只是主流的浏 ...
- 模拟登录新浪微博(Python)
PC 登录新浪微博时, 在客户端用js预先对用户名.密码都进行了加密, 而且在POST之前会GET 一组参数,这也将作为POST_DATA 的一部分. 这样, 就不能用通常的那种简单方法来模拟POST ...
- 09 Django组件之用户认证组件
没有学习Django认证组件之前使用装饰器方法 from django.shortcuts import render, HttpResponse, redirect from app01.MyFor ...
- Dart 调用C语言混合编程
Dart 调用C语言本篇博客研究Dart语言如何调用C语言代码混合编程,最后我们实现一个简单示例,在C语言中编写简单加解密函数,使用dart调用并传入字符串,返回加密结果,调用解密函数,恢复字符串内容 ...
- BZOJ 3631: [JLOI2014]松鼠的新家 树上差分 + LCA
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- 15.5.3 【Task实现细节】状态机的结构
状态机的整体结构非常简单.它总是使用显式接口实现,以实现.NET 4.5引入的 IAsync StateMachine 接口,并且只包含该接口声明的两个方法,即 MoveNext 和 SetState ...