diff --git a/db/galaxy_user_mysql.sql b/db/galaxy_user_mysql.sql index e3f27d6..7cacedf 100644 --- a/db/galaxy_user_mysql.sql +++ b/db/galaxy_user_mysql.sql @@ -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; diff --git a/src/main/java/com/nis/util/JedisUtils.java b/src/main/java/com/nis/util/JedisUtils.java index 54ea353..4c1d949 100644 --- a/src/main/java/com/nis/util/JedisUtils.java +++ b/src/main/java/com/nis/util/JedisUtils.java @@ -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 { * 可以作为获取唯一id的方法
* 将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 getList(String key, int redisDb) { @@ -145,8 +136,7 @@ public class JedisUtils { /** * 获取List缓存 * - * @param key - * 键 + * @param key 键 * @return 值 */ public static List 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) { diff --git a/src/main/java/com/nis/web/task/SyncRedisToCluster.java b/src/main/java/com/nis/web/task/SyncRedisToCluster.java index 798751e..d22dda8 100644 --- a/src/main/java/com/nis/web/task/SyncRedisToCluster.java +++ b/src/main/java/com/nis/web/task/SyncRedisToCluster.java @@ -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; } - } diff --git a/src/main/resources/nis.properties b/src/main/resources/nis.properties index 04aeaab..4bc91a4 100644 --- a/src/main/resources/nis.properties +++ b/src/main/resources/nis.properties @@ -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