经理提出新的需求,需要知道每天微信推送了多少条模板消息,成功多少条,失败多少条,想到用Redis缓存,网上查了一些资料,Redis中有方法increment,测试代码如下

  

Controller

  1. import javax.annotation.Resource;
  2.  
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.ResponseBody;
  6.  
  7. /**
  8. * @author wangqq
  9. * @version 创建时间:2018年8月10日 下午2:30:47
  10. * 类说明
  11. */
  12. @Controller
  13. @RequestMapping("test")
  14. public class TestController {
  15.  
  16. @Resource
  17. private TestService testService;
  18.  
  19. @RequestMapping("testRedis")
  20. @ResponseBody
  21. public int testRedis (){
  22. return testService.testRedis ();
  23. }
  24. }

Service

  1. import javax.annotation.Resource;
  2.  
  3. import org.springframework.data.redis.core.RedisTemplate;
  4. import org.springframework.data.redis.core.ValueOperations;
  5. import org.springframework.stereotype.Service;
  6.  
  7. /**
  8. * @author wangqq
  9. * @version 创建时间:2018年8月10日 下午2:32:13
  10. * 类说明
  11. */
  12. @Service
  13. public class TestService {
  14.  
  15. @Resource
  16. RedisTemplate<String,Object> redisTemplate;
  17.  
  18. @Resource(name="redisTemplate")
  19. private ValueOperations<String,Object> ops;
  20.  
  21. public int testRedis() {
  22. try {
  23. //此方法会先检查key是否存在,存在+1,不存在先初始化,再+1
  24. ops.increment("success", 1);
  25.  
  26. return (int) ops.get("success");
  27. } catch (Exception e) {
  28. // TODO: handle exception
  29. e.printStackTrace();
  30. }
  31.  
  32. return 0 ;
  33. }
  34.  
  35. }

直接使用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值

  1. import javax.annotation.Resource;
  2.  
  3. import org.springframework.data.redis.core.RedisTemplate;
  4. import org.springframework.data.redis.core.ValueOperations;
  5. import org.springframework.stereotype.Service;
  6.  
  7. /**
  8. * @author wangqq
  9. * @version 创建时间:2018年8月10日 下午2:32:13
  10. * 类说明
  11. */
  12. @Service
  13. public class TestService {
  14.  
  15. @Resource
  16. RedisTemplate<String,Object> redisTemplate;
  17.  
  18. @Resource(name="redisTemplate")
  19. private ValueOperations<String,Object> ops;
  20.  
  21. public int testRedis() {
  22. try {
  23. //此方法会先检查key是否存在,存在+1,不存在先初始化,再+1
  24. ops.increment("success", 1);
  25.  
  26. //return (int) ops.get("success");
  27.  
  28. return Integer.valueOf(redisTemplate.boundValueOps("success").get(0, -1));
  29. } catch (Exception e) {
  30. // TODO: handle exception
  31. e.printStackTrace();
  32. }
  33.  
  34. return 0 ;
  35. }
  36.  
  37. }

页面显示为2,因为第一次已经成功了,只是get失败了

第二种解决办法

添加一个方法 getKey

  1. import javax.annotation.Resource;
  2.  
  3. import org.springframework.dao.DataAccessException;
  4. import org.springframework.data.redis.connection.RedisConnection;
  5. import org.springframework.data.redis.core.RedisCallback;
  6. import org.springframework.data.redis.core.RedisTemplate;
  7. import org.springframework.data.redis.core.ValueOperations;
  8. import org.springframework.data.redis.serializer.RedisSerializer;
  9. import org.springframework.stereotype.Service;
  10.  
  11. /**
  12. * @author wangqq
  13. * @version 创建时间:2018年8月10日 下午2:32:13
  14. * 类说明
  15. */
  16. @Service
  17. public class TestService {
  18.  
  19. @Resource
  20. RedisTemplate<String,Object> redisTemplate;
  21.  
  22. @Resource(name="redisTemplate")
  23. private ValueOperations<String,Object> ops;
  24.  
  25. public int testRedis() {
  26. try {
  27. //此方法会先检查key是否存在,存在+1,不存在先初始化,再+1
  28. ops.increment("success", 1);
  29.  
  30. //return (int) ops.get("success");
  31.  
  32. //return Integer.valueOf(redisTemplate.boundValueOps("success").get(0, -1));
  33.  
  34. return (int) getKey("success");
  35. } catch (Exception e) {
  36. // TODO: handle exception
  37. e.printStackTrace();
  38. }
  39.  
  40. return 0 ;
  41. }
  42.  
  43. public long getKey(final String key) {
  44.  
  45. return redisTemplate.execute(new RedisCallback<Long>() {
  46. @Override
  47. public Long doInRedis(RedisConnection connection) throws DataAccessException {
  48.  
  49. RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer();
  50.  
  51. byte[] rowkey = redisSerializer.serialize(key);
  52. byte[] rowval = connection.get(rowkey);
  53.  
  54. try {
  55. String val = redisSerializer.deserialize(rowval);
  56. return Long.parseLong(val);
  57. } catch (Exception e) {
  58. return 0L;
  59. }
  60. }
  61. });
  62. }
  63.  
  64. }

页面返回

最后一步,设置每天零点过期,重新计数

  1. //当天时间
  2. Date date = new Date();
  3. //当天零点
  4. date = DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
  5. //第二天零点
  6. date = DateUtils.addDays(date, +1);
  7.  
  8. redisTemplate.expireAt("success", date);

redis实现计数--------Redis increment的更多相关文章

  1. 华为云PB级数据库GaussDB(for Redis)揭秘第八期:用高斯 Redis 进行计数

    摘要:高斯Redis,计数的最佳选择! 一.背景 当我们打开手机刷微博时,就要开始和各种各样的计数器打交道了.我们注册一个帐号后,微博就会给我们记录一组数据:关注数.粉丝数.动态数-:我们刷帖时,关注 ...

  2. Redis作者谈Redis应用场景(转)

    add by zhj : 这是Redis的作者antirez在他的技术博客中写的一篇文章 英文原文:take-advantage-of-redis-adding-it-to-your-stack 译文 ...

  3. 高可用Redis(七):Redis持久化

    1.什么是持久化 持久化就是将数据从掉电易失的内存同步到能够永久存储的设备上的过程 2.Redis为什么需要持久化 redis将数据保存在内存中,一旦Redis服务器被关闭,或者运行Redis服务的主 ...

  4. Redis 基础:Redis 数据类型

    Redis 数据类型 Redis支持五种数据类型:string(字符串).hash(哈希).list(列表).set(集合)及zset(sorted set:有序集合). String(字符串) st ...

  5. Redis之配置文件redis.conf

    解读下 redis.conf 配置文件中常用的配置项,为不显得过于臃长,已选择性删除原配置文件中部分注释. # Redis must be started with the file path as ...

  6. Redis(3) 配置文件 redis.conf

    Redis.conf 配置详解: # Redis configuration file example. # # Note that in order to read the configuratio ...

  7. 分布式数据存储 之 Redis(一) —— 初识Redis

    分布式数据存储 之 Redis(一) -- 初识Redis 为什么要学习并运用Redis?Redis有什么好处?我们步入Redis的海洋,初识Redis. 一.Redis是什么 ​ Redis 是一个 ...

  8. redis基础及redis特殊场景使用描述

    数据类型 String set list hash zset redis原理 单线程:redis是单线程+io多路复用:检查文件描述的就绪状态 对比memchached:多线程+锁 redis优势 解 ...

  9. Redis 实战 —— 14. Redis 的 Lua 脚本编程

    简介 Redis 从 2.6 版本开始引入使用 Lua 编程语言进行的服务器端脚本编程功能,这个功能可以让用户直接在 Redis 内部执行各种操作,从而达到简化代码并提高性能的作用. P248 在不编 ...

随机推荐

  1. 获取XML里指定的节点内容信息

    HttpContent bw = new StringContent(StrXml, Encoding.UTF8, "application/Xml"); var Msg = aw ...

  2. MyEclipse获取注册码

    最近刚装上MyEclipse,一直弹窗提示注册码过期,开始还能接受,到最后,每发布一个项目便弹窗提醒,顿时感觉烦了,得治理治理这个烦人的注册码,下面是一段自动生成注册名和注册码的代码,只需要直接拿来用 ...

  3. 大型工程多个目录下的Makefile写法

    1.前言 目前从事于linux下程序开发,涉及到多个文件,多个目录,这时候编译文件的任务量比较大,需要写Makefile.关于Makefile的详细内容可以参考网上流传非常广泛的<跟我一起写Ma ...

  4. handyJson的技术内核

    1.swift对象内存模型: 2.指针操作: 3.协议.泛型.扩展: 4.kvc: 1是所有实现的基础,没有内存对象(类)模型,后面的一切都我从谈起. 在1的基础上使用2进行对象模型信息的提取和转换. ...

  5. sturts2 回顾

    第一个简单的struts2例子: 1.  创建一个web project 2.  导入jar包 具体jar包在struts 的例子中的lib文件夹中copy

  6. 团体程序设计天梯赛-练习集-L1-036. A乘以B

    L1-036. A乘以B 看我没骗你吧 —— 这是一道你可以在10秒内完成的题:给定两个绝对值不超过100的整数A和B,输出A乘以B的值. 输入格式: 输入在第一行给出两个整数A和B(-100 < ...

  7. 【剑指Offer】16、合并两个排序的链表

      题目描述:   输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则.   解题思路:   首先需要判断几个特殊情况,即判断输入的两个指针是否为空.如果第一个 ...

  8. QBXT Day2

    遭遇[问题描述]你是能看到第一题的 friends呢.—— hjaN座楼房,立于城中 .第i座楼,高度 hi.你需要一开始选择座楼,开始跳楼. 在第 i座楼准备跳需要 ci的花费. 每次可以跳到任何一 ...

  9. SSH(远程登录)

    在linux中SSH服务对应两个配置文件: ssh特点:在传输数据的时候,对文件加密后传输. ssh作用:为远程登录会话和其他网络服务提供安全性协议. ssh小结: 1.SSH是安全的加密协议,用于远 ...

  10. python第十周:进程、协程、IO多路复用

    多进程(multiprocessing): 多进程的使用 multiprocessing是一个使用类似于线程模块的API支持产生进程的包. 多处理包提供本地和远程并发,通过使用子进程而不是线程有效地侧 ...