为配置下发添加分布式锁,确保maat_version一致

This commit is contained in:
renkaige
2018-11-26 15:10:32 +08:00
parent 6c6dfbcf7c
commit b7f46e3293
6 changed files with 311 additions and 156 deletions

View File

@@ -211,12 +211,22 @@ public final class Constants {
*是否使用Minio
*/
public static final Boolean IS_USE_MINIO = Configurations.getBooleanProperty("isUseMinio", true);
public static final int MAXTHREADNUM = Configurations.getIntProperty("maxThreadNum", 10);
public static final int EVERTHREADNUM = Configurations.getIntProperty("everThreadNum", 10000);
/**
* 保存请求内容时最大的资源列表size
*/
public static final int MAX_LIST_SIZE = Configurations.getIntProperty("maxListSize", 10);
/**
* redis分布式锁超时时间,默认五分钟,3000秒
*/
public static final Long REDISLOCKTIME=Configurations.getLongProperty("redisLockTime", 3000);
/**
* 获取redis分布式锁失败后的尝试获取锁的次数,每次失败暂停一秒钟后再次尝试
*/
public static final Long REDISRETRYNUM=Configurations.getLongProperty("redisRetryNum", 5);
}

View File

@@ -1,5 +1,6 @@
package com.nis.util;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
@@ -16,7 +17,8 @@ import com.nis.web.service.SpringContextHolder;
public class JedisUtils {
private static Logger logger = LoggerFactory.getLogger(JedisUtils.class);
private static JedisPool jedisPool = SpringContextHolder.getBean(JedisPool.class);
private static final JedisPool jedisPool = SpringContextHolder.getBean(JedisPool.class);
/**
* 获取缓存
*
@@ -232,7 +234,7 @@ public class JedisUtils {
jedis.select(redisDb);
} catch (JedisException e) {
returnBrokenResource(jedis);
logger.error("获取redis连接失败,异常信息:{}" ,ExceptionUtil.getExceptionMsg(e));
logger.error("获取redis连接失败,异常信息:{}", ExceptionUtil.getExceptionMsg(e));
throw new ServiceRuntimeException("获取redis连接失败,请联系管理员检查程序",
RestBusinessCode.CannotConnectionRedis.getValue());
}
@@ -298,4 +300,72 @@ public class JedisUtils {
return ObjectUtils.unserialize(bytes);
}
// 设置成功返回的结果OK
private static final String LOCK_SUCCESS = "OK";
// NX -- Only set the key if it does not already exist. XX -- Only set the key
// if it already exist
private static final String SET_IF_NOT_EXIST = "NX";
// 失效单位秒(EX)还是毫秒(PX)
private static final String SET_WITH_EXPIRE_TIME = "EX";
private static final Long UNLOCK_SUCCESS = 1L;
/**
* 尝试获取分布式锁,如果没有key就set,有key就不操作
*
* @param requestId
* 请求标识(UUID.randomUUID().toString()),正常情况下是谁加的锁,谁去解锁不能a加的锁,b去解锁
* @return 是否获取成功
*/
public static Boolean lock(String requestId) {
String key = "redisDistributedLock";
String var1 = getResource(0).set(key, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME,
Constants.REDISLOCKTIME);
if (LOCK_SUCCESS.equals(var1)) {
return true;
}
return false;
}
/**
* 解锁操作
*
* @param value
* 客户端标识(requestId)
* @return
*/
public static Boolean unLock(String value) {
String key = "redisDistributedLock";
// 这个字符串是个lua脚本代表的意思是如果根据key拿到的value跟传入的value相同就执行del否则就返回0【保证安全性】
String luaScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else return 0 end";
// 这个命令就是去执行lua脚本KEYS的集合就是第二个参数ARGV的集合就是第三参数【保证解锁的原子操作】
Object var2 = getResource(0).eval(luaScript, Collections.singletonList(key), Collections.singletonList(value));
if (UNLOCK_SUCCESS == var2) {
return true;
}
return false;
}
/**
* 重试机制
*
* @param value
* 客户端标识
* @return
*/
public static Boolean lockRetry(String value) {
Boolean flag = false;
try {
for (int i = 0; i < Constants.REDISRETRYNUM; i++) {
flag = lock(value);
if (flag) {
break;
}
Thread.sleep(1000);
}
} catch (Exception e) {
logger.error("尝试获取redis分布式锁失败,失败原因:{}", ExceptionUtil.getExceptionMsg(e));
}
return flag;
}
}