redis代码封装,及分布式锁实现

package com.smallrig.srm.redis;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @version 1.0.0
 * @aurhor chencl
 * @date 2020/4/28 0028
 * @描述: redis缓存服务端接口
 */
public interface RedisService {

    void setExpireTime(String key, long seconds);

    void setExpireDate(String key, Date date);

    Boolean exists(String key);

    void delete(String key);

    void delete(List keys);

    void put(String key, String value);

    void put(String key, String value, long seconds);

    Object get(String key);

    Long leftPush(String key, Object value);

    Long leftPush(String key, Object value, long seconds);

    Long rightPush(String key, Object value);

    Long rightPush(String key, Object value, long seconds);

    Object leftPop(String key);

    Object rightPop(String key);

    Long listLength(String key);

    List listRange(String key, int start, int end);

    void listRemove(String key, long i, Object value);

    String index(String key, long index);

    void listSet(String key, long index, Object value);

    void listTrim(String key, long start, int end);

    void setAdd(String key, Object... values);

    void setAdd(String key, long seconds, Object... values);

    Boolean setContains(String key, Object value);

    long setRemove(String key, Object... values);

    Set setMembers(String key);

    void hashPut(String key, String hkey, Object hvalue);

    void hashPut(String key, String hkey, Object hvalue, long seconds);

    Object hashGet(String key, String hkey);

    long hashRemove(String key, Object... hkey);

    Map hashEntries(String key);

    Set hashKeys(String key);

    Boolean hashHasKey(String key, String hashKey);

    Long hashSize(String key);

    void hashPutAll(String key, Map m);

    long getExpire(String key);

    Set getKeys(String pattern);

    long increment(String key);

    Boolean tryGetDistributedLock(String lockKey);

    Boolean releaseDistributedLock(String lockKey);


}

 

package com.smallrig.srm.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.TimeoutUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @version 1.0.0
 * @aurhor chencl
 * @date 2020/4/28 0028
 * @描述: redis缓存客户端实现
 */
@Service
@Slf4j
public class RedisServiceImpl implements RedisService {

    @Autowired
    RedisTemplate objectRedisTemplate;

    private static final long SHORT_SECONDS_TIME;

    private static final String LOCK_PREFIX  = "redis:distributed:lock";

    private static final int LOCK_EXPIRE  = 6000;

    static {
        SHORT_SECONDS_TIME = TimeoutUtils.toSeconds(7L, TimeUnit.DAYS);
    }

    @Override
    public void setExpireTime(String key, long seconds) {
        if(seconds < 1L) {
            seconds = SHORT_SECONDS_TIME;
        }

        this.objectRedisTemplate.expire(key, seconds, TimeUnit.SECONDS);
    }

    @Override
    public void setExpireDate(String key, Date date) {
        if(date == null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(5, 7);
            date = calendar.getTime();
        }

        this.objectRedisTemplate.expireAt(key, date);
    }

    @Override
    public Boolean exists(String key) {
        return this.objectRedisTemplate.hasKey(key);
    }

    @Override
    public void delete(String key) {
        this.objectRedisTemplate.delete(key);
    }

    @Override
    public void delete(List keys) {
        this.objectRedisTemplate.delete(keys);
    }

    @Override
    public void put(String key, String value) {
        this.objectRedisTemplate.boundValueOps(key).set(value);
    }

    @Override
    public void put(String key, String value, long seconds) {
        Assert.hasText(key);
        this.objectRedisTemplate.boundValueOps(key).set(value);
        this.setExpireTime(key, seconds);
    }

    @Override
    public Object get(String key) {
        return this.objectRedisTemplate.boundValueOps(key).get();
    }

    @Override
    public Long leftPush(String key, Object value) {
        Assert.hasText(key);
        return this.objectRedisTemplate.opsForList().leftPush(key, value);
    }

    @Override
    public Long leftPush(String key, Object value, long seconds) {
        Long resultLong = this.leftPush(key, value);
        this.setExpireTime(key, seconds);
        return resultLong;
    }

    @Override
    public Long rightPush(String key, Object value) {
        Assert.hasText(key);
        return this.objectRedisTemplate.opsForList().rightPush(key, value);
    }

    @Override
    public Long rightPush(String key, Object value, long seconds) {
        Long resultLong = this.rightPush(key, value);
        this.setExpireTime(key, seconds);
        return resultLong;
    }

    @Override
    public Object leftPop(String key) {
        return this.objectRedisTemplate.opsForList().leftPop(key);
    }

    @Override
    public Object rightPop(String key) {
        return this.objectRedisTemplate.opsForList().rightPop(key);
    }

    @Override
    public Long listLength(String key) {
        return this.objectRedisTemplate.opsForList().size(key);
    }

    @Override
    public List listRange(String key, int start, int end) {
        return this.objectRedisTemplate.opsForList().range(key, (long)start, (long)end);
    }

    @Override
    public void listRemove(String key, long i, Object value) {
        this.objectRedisTemplate.opsForList().remove(key, i, value);
    }

    @Override
    public String index(String key, long index) {
        return (String)this.objectRedisTemplate.opsForList().index(key, index);
    }

    @Override
    public void listSet(String key, long index, Object value) {
        this.objectRedisTemplate.opsForList().set(key, index, value);
    }

    @Override
    public void listTrim(String key, long start, int end) {
        this.objectRedisTemplate.opsForList().trim(key, start, (long)end);
    }

    @Override
    public void setAdd(String key, Object... values) {
        Assert.hasText(key);
        this.objectRedisTemplate.opsForSet().add(key, values);
    }

    @Override
    public void setAdd(String key, long seconds, Object... values) {
        this.setAdd(key, values);
        this.setExpireTime(key, seconds);
    }

    @Override
    public Boolean setContains(String key, Object value) {
        return this.objectRedisTemplate.opsForSet().isMember(key, value);
    }

    @Override
    public long setRemove(String key, Object... values) {
        return this.objectRedisTemplate.opsForSet().remove(key, values).longValue();
    }

    @Override
    public Set setMembers(String key) {
        return this.objectRedisTemplate.opsForSet().members(key);
    }

    @Override
    public void hashPut(String key, String hkey, Object hvalue) {
        Assert.hasText(key);
        Assert.hasText(hkey);
        this.objectRedisTemplate.opsForHash().put(key, hkey, hvalue);
    }

    @Override
    public void hashPut(String key, String hkey, Object hvalue, long seconds) {
        this.hashPut(key, hkey, hvalue);
        this.setExpireTime(key, seconds);
    }

    @Override
    public Object hashGet(String key, String hkey) {
        Assert.hasText(key);
        Assert.hasText(hkey);
        return this.objectRedisTemplate.opsForHash().get(key, hkey);
    }

    @Override
    public long hashRemove(String key, Object... hkey) {
        Assert.hasText(key);
        return this.objectRedisTemplate.opsForHash().delete(key, hkey).longValue();
    }

    @Override
    public Map hashEntries(String key) {
        Assert.hasText(key);
        BoundHashOperations ops = this.objectRedisTemplate.boundHashOps(key);
        return ops.entries();
    }

    @Override
    public Set hashKeys(String key) {
        return this.objectRedisTemplate.opsForHash().keys(key);
    }

    @Override
    public Boolean hashHasKey(String key, String hashKey) {
        return this.objectRedisTemplate.opsForHash().hasKey(key, hashKey);
    }

    @Override
    public Long hashSize(String key) {
        return this.objectRedisTemplate.opsForHash().size(key);
    }

    @Override
    public void hashPutAll(String key, Map m) {
        this.objectRedisTemplate.opsForHash().putAll(key, m);
    }

    @Override
    public long getExpire(String key) {
        return this.objectRedisTemplate.getExpire(key).longValue();
    }

    @Override
    public Set getKeys(String pattern) {
        return this.objectRedisTemplate.keys(pattern);
    }

    @Override
    public long increment(String key) {
        return this.objectRedisTemplate.boundValueOps(key).increment(1L).longValue();
    }

    @Override
    public Boolean tryGetDistributedLock(String lockKey) {
        String lock = LOCK_PREFIX + lockKey;
       return (Boolean) this.objectRedisTemplate.execute((RedisCallback) connection -> {
            long expireAt = System.currentTimeMillis() + LOCK_EXPIRE + 1;
            Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes());
            if (acquire) {
                return true;
            } else {
                byte[] value = connection.get(lock.getBytes());
                if (Objects.nonNull(value) && value.length > 0) {
                    long expireTime = Long.parseLong(new String(value));
                    // 如果锁已经过期
                    if (expireTime < System.currentTimeMillis()) {
                        // 重新加锁,防止死锁
                        byte[] oldValue = connection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes());
                        return Long.parseLong(new String(oldValue)) < System.currentTimeMillis();
                    }
                }
            }
            return false;
        });
    }

    @Override
    public Boolean releaseDistributedLock(String lockKey) {
        String lock = LOCK_PREFIX + lockKey;
        return  this.objectRedisTemplate.delete(lock);
    }


}

分布式锁使用例子

String key="head_sync_fba_status"+headNo;
Boolean b=redisService.tryGetDistributedLock(key);
if(!b){
   return ResponseBean.buildFail(50002,"请勿重复提交!");
}
HeadFbaSeparateWarehouse warehouse=headFbaSeparateWarehouseMapper.queryByShipmentIdAndStatus(shipmentId,null);
HeadFbaPlatformInformation platformInformation=headFbaPlatformInformationMapper.queryByPlanNo(warehouse.getPlanNo());
//获取公司地址id
HeadFbaStartAddress headFbaStartAddress=headFbaStartAddressMapper.queryStartAddressById(platformInformation.getOriginConfigId());
//封装获取退货地址
Address shipFromAddress=headFbaPlatformInformationService.getShipFromAddress(headFbaStartAddress);
AmazonInterConfig amazonInterConfig = headFbaPlatformInformationMapper.queryAmazonInterConfigByChannelId(platformInformation.getChannelId());
Map parameterMap = headFbaPlatformInformationService.queryAmazonInterConfigByChannelId(amazonInterConfig);
//封装数据
UpdateInboundShipmentRequest request = headFbaPlatformInformationService.getUpdateInboundShipmentRequest(warehouse,shipFromAddress);
if(request!=null){
   parameterMap =headFbaPlatformInformationService.getUpdateInboundShipment(request, parameterMap, ShipmentStatusEnum.SHIPPED.getCode());
   //签名
   String url=amazonInterConfig.getSiteUrl()+ CommonConstant.CREATE_INBOUND_SHIPMENT_PLAN_URL;
   String str= HttpUtil.calculateStringToSignV2(parameterMap,amazonInterConfig.getSiteUrl());
   if(org.apache.commons.lang3.StringUtils.isBlank(str)){
      //更新同步状态为失败
      getDao().updateFbaStatusByHeadNo(1,headNo);
      //释放锁
      redisService.releaseDistributedLock(key);
      return ResponseBean.buildFail(50001,"拼接签名串失败");
   }
   String signature = HttpUtil.sign(str, amazonInterConfig.getSecretKey());
   if(org.apache.commons.lang3.StringUtils.isBlank(signature)){
      //更新同步状态为失败
      getDao().updateFbaStatusByHeadNo(1,headNo);
      log.error("更新亚马逊货件状态为SHIPPED:{}签名失败",shipmentId);
      //释放锁
      redisService.releaseDistributedLock(key);
      return ResponseBean.buildFail(50002,"签名失败");
   }
   parameterMap.put("Signature", HttpUtil.urlEncode(signature));
   log.info("调用亚马逊提交货件信息请求参数:{}", parameterMap.toString());
   String paramStr = HttpUtil.sortParams(new StringBuilder(), parameterMap);
   String xml = HttpUtil.doPost(url, paramStr);
   if(org.apache.commons.lang3.StringUtils.isBlank(xml)){
      //更新同步状态为失败
      getDao().updateFbaStatusByHeadNo(1,headNo);
      log.error("请求更新亚马逊货件状态为SHIPPED:{}接口失败",shipmentId);
      //释放锁
      redisService.releaseDistributedLock(key);
      return ResponseBean.buildFail(50003,"请求更新亚马逊货件状态接口失败");
   }
   if (xml.contains("UpdateInboundShipmentResponse")) {
      //更新同步状态为成功
      getDao().updateFbaStatusByHeadNo(2,headNo);
      log.info("请求更新亚马逊货件状态为SHIPPED:{}接口成功",shipmentId);
      //释放锁
      redisService.releaseDistributedLock(key);
      return ResponseBean.buildSuccess();
   } else {
      //处理错误消息
      if (xml.contains("ErrorResponse")) {
         //更新同步状态为失败
         getDao().updateFbaStatusByHeadNo(1,headNo);
         log.error("解析亚马逊错误消息开始=================================");
         InputStream inputStream2 = new ByteArrayInputStream(xml.getBytes());
         net.sf.json.JSONObject obj2 = JavaBeanXmlUtil.parseXML(inputStream2);
         String jsonObject = obj2.getJSONObject("Error").getString("Message");
         log.error("解析亚马逊错误消息结束=================================,:{}", jsonObject);
         //释放锁
         redisService.releaseDistributedLock(key);
         return ResponseBean.buildFail(50004,jsonObject);
      }
   }
}
return ResponseBean.buildFail(50005,"未知错误");

 

 

 

你可能感兴趣的:(redis)