数据分片(任务执行)
String data = dataAllotService.getMachineAllotData(); paramMap.put("TRANS_NO_SUB", data); List<TblChannelsTransaction> list = channelsTransExceptionLogicImpl.queryTransExceptionList(paramMap);
<if test="TRANS_NO_SUB != null and TRANS_NO_SUB !='' ">
AND SUBSTRB(TRANS_NO,-1) in (${TRANS_NO_SUB})
</if>
@Service public class DataAllotServiceImpl implements DataAllotService { private static Logger logger = LoggerFactory.getLogger("DataAllotServiceImpl"); private final static String MACHINENAME_SUFFIX = "_IS_LIVE"; private final static String MACHINENAME_REG = "TASK_NODE_REG"; private String REDIS_KEY = BasisConstants.Redis_Basic_key; private static String machineName; @Autowired private CacheService cacheService; private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); @PostConstruct public void startDataSplit() { scheduledExecutorService.scheduleAtFixedRate(new Runnable() { public void run() { sendHeartBeat(); } }, 1, 6, TimeUnit.SECONDS); } /** * 节点注册和心跳设置 */ public void sendHeartBeat() { try { if(StringUtils.isEmpty(getMachineName())){ logger.error("[DataAllotServiceImpl]未获取到应用名称"); }else{ String taskSplitSync = cacheService.get(REDIS_KEY,"TASK_SPLIT_SYNC"); if(StringUtils.isEmpty(taskSplitSync)) { cacheService.setex(REDIS_KEY, getMachineName() + MACHINENAME_SUFFIX, 20, getMachineName());//心跳写入 cacheService.sadd(REDIS_KEY, MACHINENAME_REG, getMachineName());//注册 logger.info("[DataAllotServiceImpl]sendHeartBeat,心跳写入成功"); }else{ logger.info("[DataAllotServiceImpl]sendHeartBeat,正在等待心跳写入,同步标示taskSplitSync为:" + taskSplitSync); } } } catch (Exception e) { logger.error("[DataAllotServiceImpl].sendHeartBeat出现异常:", e); } } public String getMachineAllotData(){ String machineAllotData = ""; try { machineAllotData = cacheService.get(REDIS_KEY, getMachineName()); } catch (Exception e) { logger.error("[DataAllotServiceImpl].getMachineAllotData出现异常:", e); } return machineAllotData; } public String getMachineName(){ if(!StringUtils.isEmpty(machineName)){ return machineName; } InetAddress inet; String ip = ""; try { inet = InetAddress.getLocalHost(); ip = inet.getHostAddress(); } catch (UnknownHostException e) { logger.error("[DataAllotServiceImpl]获取IP出现异常,e:" + e.getMessage(), e); } String fullPath = Thread.currentThread().getContextClassLoader().getResource("").toString(); logger.info("[DataAllotServiceImpl]fullPath:" + fullPath); if(fullPath.indexOf("/webapps") == -1){ return null; } String lPath = fullPath.substring(0,fullPath.indexOf("/webapps")); String projectName = lPath.substring(lPath.lastIndexOf("/") + 1); logger.info("[DataAllotServiceImpl]ip:" + ip + ",projectName:" + projectName); if(StringUtils.isEmpty(ip)){ return null; } machineName = ip.replaceAll("\\.", "") + projectName; return machineName; } }
/** * @Title FormatDateUtils * @package cn.com.gome.pay.admin.logic.impl * @author tianlong * @company cn.com.gome * @Date 2016/12/6 * @version V1.0 */ package cn.com.gome.pay.admin.logic.impl; import cn.com.gome.common.security.md5.MD5Util; import cn.com.gome.frame.cache.ApplicationCache; import cn.com.gome.pay.admin.logic.TaskDataAllotListenerLogic; import com.alibaba.dubbo.common.utils.StringUtils; import com.gome.service.CacheService; import org.apache.commons.collections.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * @author tianlong * @ClassName TaskDataAllotListenerLogicImpl * @Description 后台管理定时任务分片监听器 * @Date 2017/06/12 */ @Service public class TaskDataAllotListenerLogicImpl implements TaskDataAllotListenerLogic { private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); @Autowired private CacheService cacheService; private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); @PostConstruct public void startDataSplit() { scheduledExecutorService.scheduleAtFixedRate(new Runnable() { public void run() { taskDataSplit(); } }, 1, 15, TimeUnit.SECONDS); } public void taskDataSplit() { logger.info("定时任务监听数据分片TaskDataAllotListenerLogic.startDataSplit开始运行"); String REDIS_KEY = ApplicationCache.getInstance().getStr("REDIS_KEY"); try { //1.获取注册的定时任务实例 Set<String> regNodes = cacheService.smembers(REDIS_KEY, "TASK_NODE_REG"); if(CollectionUtils.isNotEmpty(regNodes)){ logger.info("定时任务监听数据分片TaskDataAllotListenerLogic.startDataSplit注册实例:" + Arrays.toString(regNodes.toArray())); }else { logger.info("定时任务监听数据分片TaskDataAllotListenerLogic.startDataSplit注册实例:0"); return; } String liveNode = ""; List<String> liveNodes = new ArrayList<String>(); //2.获取存活的实例 for (String reg : regNodes) { String nodeLive = cacheService.get(REDIS_KEY,reg+"_IS_LIVE"); if(StringUtils.isNotEmpty(nodeLive)){ liveNodes.add(nodeLive); liveNode += reg; } } logger.info("定时任务监听数据分片TaskDataAllotListenerLogic.startDataSplit存活的实例:" + liveNode); //3.判断是否需要重新分配分片数据 if(StringUtils.isNotEmpty(liveNode)){ String md5LiveNode = cacheService.get(REDIS_KEY,"TASK_NODE_MD5"); String md5Node = MD5Util.encodeMessage(liveNode.getBytes()); if(!md5Node.equals(md5LiveNode)){ cacheService.setex(REDIS_KEY, "TASK_NODE_MD5",120, md5Node);//存活120秒强制计算 splitData(REDIS_KEY,liveNodes); } } } catch (Exception e) { logger.error("定时任务监听数据分片TaskDataAllotListenerLogic.startDataSplit运行异常", e); } logger.info("定时任务监听数据分片TaskDataAllotListenerLogic.startDataSplit结束运行"); } private void splitData(String REDIS_KEY,List<String> liveNodes) { //1.分片数据 Integer[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Map<String, String> split = new HashMap<String, String>(); for (int i = 0; i < numbers.length; i++) { int index = numbers[i] % liveNodes.size(); if (split.containsKey(liveNodes.get(index))) { String s = split.get(liveNodes.get(index)); split.put(liveNodes.get(index), s + "," + numbers[i]); } else { split.put(liveNodes.get(index), String.valueOf(numbers[i])); } } //2.输出数据分片 for (Map.Entry<String, String> entry : split.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); cacheService.setex(REDIS_KEY,entry.getKey(),150,entry.getValue());//存活150秒 logger.info("定时任务监听数据分片TaskDataAllotListenerLogic.startDataSplit的result:" + " key= " + entry.getKey() + " and value= " + entry.getValue()); } } }