数据分片(任务执行)
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());
}
}
}

浙公网安备 33010602011771号