redis實現計數--------Redis increment

  經理提出新的需求,須要知道天天微信推送了多少條模板消息,成功多少條,失敗多少條,想到用Redis緩存,網上查了一些資料,Redis中有方法increment,測試代碼以下java

  

Controllerweb

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 ();
    }
}

 

Serviceredis

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序列化以後,反序列化失敗。解決辦法:spring

 

第一種解決辦法緩存

用 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失敗了app

第二種解決辦法ide

添加一個方法 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;
                }
            }
        });
    }
    
}

 

頁面返回spa

 

 最後一步,設置天天零點過時,從新計數

//當天時間
Date date = new Date();
//當天零點
date = DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
//次日零點
date = DateUtils.addDays(date, +1);

redisTemplate.expireAt("success", date);
相關文章
相關標籤/搜索