1.修改程序中获取redis连接为哨兵模式并测试
2.修改实时统计配置同步到redis集群时使用分布式锁避免多tomcat重复执行
This commit is contained in:
@@ -6,9 +6,9 @@ set global read_only=0;
|
||||
|
||||
create user 'galaxy'@'%' identified by 'ceiec2018!';
|
||||
|
||||
create database galaxy_test DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
create database galaxy-service DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
grant all privileges on galaxy_test.* to 'galaxy'@'%' identified by 'ceiec2018!';
|
||||
grant all privileges on galaxy-service.* to 'galaxy'@'%' identified by 'ceiec2018!';
|
||||
|
||||
flush privileges;
|
||||
|
||||
|
||||
@@ -6,24 +6,22 @@ import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.nis.restful.RestBusinessCode;
|
||||
import com.nis.restful.ServiceRuntimeException;
|
||||
import com.nis.web.service.SpringContextHolder;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisSentinelPool;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
|
||||
public class JedisUtils {
|
||||
private static Logger logger = LoggerFactory.getLogger(JedisUtils.class);
|
||||
private static final JedisPool jedisPool = SpringContextHolder.getBean(JedisPool.class);
|
||||
|
||||
/**
|
||||
* 获取缓存
|
||||
*
|
||||
* @param key
|
||||
* 键
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public static String get(String key, int redisDb) {
|
||||
@@ -48,8 +46,7 @@ public class JedisUtils {
|
||||
/**
|
||||
* 获取缓存
|
||||
*
|
||||
* @param key
|
||||
* 键
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public static Object getObject(String key, int redisDb) {
|
||||
@@ -74,10 +71,8 @@ public class JedisUtils {
|
||||
* <b>可以作为获取唯一id的方法</b><br/>
|
||||
* 将key对应的value加上指定的值,只有value可以转为数字时该方法才可用
|
||||
*
|
||||
* @param String
|
||||
* key
|
||||
* @param long
|
||||
* number 要减去的值
|
||||
* @param String key
|
||||
* @param long number 要减去的值
|
||||
* @return long 相加后的值
|
||||
*/
|
||||
public static long incrBy(String key, long number, int redisDb) {
|
||||
@@ -90,12 +85,9 @@ public class JedisUtils {
|
||||
/**
|
||||
* 设置缓存
|
||||
*
|
||||
* @param key
|
||||
* 键
|
||||
* @param value
|
||||
* 值
|
||||
* @param cacheSeconds
|
||||
* 超时时间,0为不超时
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param cacheSeconds 超时时间,0为不超时
|
||||
* @return
|
||||
*/
|
||||
public static String set(String key, String value, int cacheSeconds, int redisDb) {
|
||||
@@ -120,8 +112,7 @@ public class JedisUtils {
|
||||
/**
|
||||
* 获取List缓存
|
||||
*
|
||||
* @param key
|
||||
* 键
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public static List<String> getList(String key, int redisDb) {
|
||||
@@ -145,8 +136,7 @@ public class JedisUtils {
|
||||
/**
|
||||
* 获取List缓存
|
||||
*
|
||||
* @param key
|
||||
* 键
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public static List<Object> getObjectList(String key, int redisDb) {
|
||||
@@ -174,8 +164,7 @@ public class JedisUtils {
|
||||
/**
|
||||
* 缓存是否存在
|
||||
*
|
||||
* @param key
|
||||
* 键
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public static boolean exists(String key, int redisDb) {
|
||||
@@ -197,8 +186,7 @@ public class JedisUtils {
|
||||
/**
|
||||
* 缓存是否存在
|
||||
*
|
||||
* @param key
|
||||
* 键
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public static boolean existsObject(String key, int redisDb) {
|
||||
@@ -224,13 +212,15 @@ public class JedisUtils {
|
||||
* @throws JedisException
|
||||
*/
|
||||
public static Jedis getResource(int redisDb) throws JedisException {
|
||||
Jedis jedis = null;
|
||||
if (jedisPool == null) {
|
||||
JedisSentinelPool jedisSentinelPool = SpringContextHolder.getBean(JedisSentinelPool.class);
|
||||
|
||||
if (jedisSentinelPool == null) {
|
||||
throw new ServiceRuntimeException("redis连接池为空,请联系管理员检查程序",
|
||||
RestBusinessCode.CannotConnectionRedis.getValue());
|
||||
}
|
||||
Jedis jedis = null;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
jedis = jedisSentinelPool.getResource();
|
||||
jedis.select(redisDb);
|
||||
} catch (JedisException e) {
|
||||
returnBrokenResource(jedis);
|
||||
@@ -312,8 +302,7 @@ public class JedisUtils {
|
||||
/**
|
||||
* 尝试获取分布式锁,如果没有key就set,有key就不操作
|
||||
*
|
||||
* @param requestId
|
||||
* 请求标识(UUID.randomUUID().toString()),正常情况下是谁加的锁,谁去解锁不能a加的锁,b去解锁
|
||||
* @param requestId 请求标识(UUID.randomUUID().toString()),正常情况下是谁加的锁,谁去解锁不能a加的锁,b去解锁
|
||||
* @return 是否获取成功
|
||||
*/
|
||||
public static Boolean lock(String requestId) {
|
||||
@@ -329,8 +318,7 @@ public class JedisUtils {
|
||||
/**
|
||||
* 解锁操作
|
||||
*
|
||||
* @param value
|
||||
* 客户端标识(requestId)
|
||||
* @param value 客户端标识(requestId)
|
||||
* @return
|
||||
*/
|
||||
public static Boolean unLock(String value) {
|
||||
@@ -348,8 +336,7 @@ public class JedisUtils {
|
||||
/**
|
||||
* 重试机制
|
||||
*
|
||||
* @param value
|
||||
* 客户端标识
|
||||
* @param value 客户端标识
|
||||
* @return
|
||||
*/
|
||||
public static Boolean lockRetry(String value) {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.nis.web.task;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -15,6 +17,7 @@ import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.nis.util.Configurations;
|
||||
import com.nis.util.Constants;
|
||||
import com.nis.util.ExceptionUtil;
|
||||
import com.nis.util.JedisUtils;
|
||||
import com.nis.web.service.restful.ConfigJedisServiceimpl;
|
||||
@@ -33,15 +36,12 @@ public class SyncRedisToCluster {
|
||||
|
||||
@Autowired
|
||||
private JedisCluster jedisCluster;
|
||||
// @Autowired
|
||||
// private JedisSentinelPool jedisSentinelPool;
|
||||
|
||||
// @Scheduled(cron = "0/3 * * * * ?")
|
||||
// @Scheduled(cron = "${syncRedisToClusterCron}")
|
||||
@Scheduled(cron = "${syncRedisToClusterCron}")
|
||||
public void syncRedisToCluster() {
|
||||
String requestId = UUID.randomUUID().toString();
|
||||
try {
|
||||
String rpopRedisList = rpopRedisList("SyncRedisToCluster");
|
||||
if (rpopRedisList != null) {//避免集群环境下同一秒钟所有的机器都执行这个定时任务
|
||||
if (lock(requestId)) {// 避免集群环境下同一秒钟所有的机器都执行这个定时任务
|
||||
// keys("EFFECTIVE_RULE*");
|
||||
// keys("OBSOLETE_RULE*");
|
||||
String clusterMaatVersionStr = jedisCluster.get("MAAT_VERSION");
|
||||
@@ -75,12 +75,13 @@ public class SyncRedisToCluster {
|
||||
logger.info("redis配置库中和redis集群中的MAAT_VERSION都为null,暂时不执行全量同步");
|
||||
}
|
||||
}
|
||||
lpushRedisList("SyncRedisToCluster", "1");
|
||||
} else {
|
||||
logger.info("没有从rediscluster中获取到SyncRedisToCluster的值,暂时不执行数据同步!");
|
||||
logger.info("没有从rediscluster中获取到configSyncDistributedLock分布式锁,暂时不执行数据同步!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("同步配置库配置到3A-redisCluster失败,失败原因:{}", ExceptionUtil.getExceptionMsg(e));
|
||||
} finally {
|
||||
unlock(requestId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,29 +199,45 @@ public class SyncRedisToCluster {
|
||||
logger.info("向redis集群同步数据成功");
|
||||
}
|
||||
|
||||
// 设置成功返回的结果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;
|
||||
|
||||
/**
|
||||
* 存储Redis队列,顺序存储
|
||||
* 尝试获取分布式锁,如果没有key就set,有key就不操作
|
||||
*
|
||||
* @param key
|
||||
* redis键名
|
||||
* @param value
|
||||
* 键值
|
||||
* @param requestId 请求标识(UUID.randomUUID().toString()),正常情况下是谁加的锁,谁去解锁不能a加的锁,b去解锁
|
||||
* @return 是否获取成功
|
||||
*/
|
||||
public void lpushRedisList(String key, String value) {
|
||||
// LPUSH SyncRedisToCluster "1"
|
||||
jedisCluster.lpush(key, value);
|
||||
logger.info("向redis集群的{}中lpush了一个值{}", key, value);
|
||||
public Boolean lock(String requestId) {
|
||||
String key = "configSyncDistributedLock";
|
||||
String var1 = jedisCluster.set(key, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, Constants.REDISLOCKTIME);
|
||||
if (LOCK_SUCCESS.equals(var1)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除并获取列表最后一个元素
|
||||
* 解除redis分布式锁
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
* @param requestId
|
||||
*/
|
||||
public String rpopRedisList(String key) {
|
||||
// RPOP SyncRedisToCluster
|
||||
return jedisCluster.rpop(key);
|
||||
protected boolean unlock(String requestId) {
|
||||
String key = "configSyncDistributedLock";
|
||||
// 这个字符串是个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 = jedisCluster.eval(luaScript, Collections.singletonList(key),
|
||||
Collections.singletonList(requestId));
|
||||
if (UNLOCK_SUCCESS == var2) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ maatTestLogPath=c:/maat/mmat.log
|
||||
mmSampleDstPath=/home/mesasoft/{tableType}/full/{fileName}
|
||||
|
||||
##定时将redis主从库的实时统计数据同步到redis集群中
|
||||
syncRedisToClusterCron=0/10 * * * * ?
|
||||
syncRedisToClusterCron=1 * * * * ?
|
||||
#文件服务器是否使用Minio
|
||||
isUseMinio=true
|
||||
|
||||
|
||||
Reference in New Issue
Block a user