package com.hqyg.disjob.register.job; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.utils.ZKPaths; import org.springframework.stereotype.Service; import com.hqyg.disjob.common.Constants; import com.hqyg.disjob.common.util.LoggerUtil; import com.hqyg.disjob.register.center.pool.ThreadLocalClient; import com.hqyg.disjob.register.domain.EjobServerInfo; import com.hqyg.disjob.register.domain.Job; import com.hqyg.disjob.register.repository.ZnodeApi; import com.hqyg.disjob.rpc.client.HURL; import com.hqyg.disjob.slaver.utils.SlaveUtils; import com.google.common.collect.Lists; import com.google.gson.Gson; /** * 服务器集群操作服务类 * @author Disjob * */ @Service("initServerExecuteJobService") public class EjobServerServiceImpl implements EjobServerService { @Resource private ZnodeApi znodeApi; @Resource private ThreadLocalClient threadLocalClient; public boolean distributeJob(CuratorFramework client) { //是否全部机器都启动才触发job分配??? //是否每次启动都重新分配job??? // 获得所有的job节点 String jobPath = ZKPaths.makePath(Constants.ROOT, Constants.APP_JOB_NODE_ROOT); List<String> jobGroupLst = znodeApi.getChildren(client, jobPath); Map<String, List<String>> groupJobMap = new HashMap<String, List<String>>(); for (String groupStr : jobGroupLst) { String groupPath = ZKPaths.makePath(Constants.ROOT, Constants.APP_JOB_NODE_ROOT, Constants.PATH_SEPARATOR + groupStr); List<String> jobNameLst = znodeApi.getChildren(client, groupPath); LoggerUtil.debug("distribute job, group: " + groupStr + "jobListSize: " + jobNameLst.size()); groupJobMap.put(groupStr, jobNameLst); } // 获得所有ready状态的slave机器的ip节点 String slavePath = ZKPaths.makePath(Constants.ROOT, Constants.EJOB_SERVER_NODE_ROOT, Constants.EJOB_SERVER_NODE_SLAVE); List<String> slaveIpLst = znodeApi.getChildren(client, slavePath); List<String> readyIpLst = new ArrayList<String>(); for(String ip : slaveIpLst){ String infoPath = ZKPaths.makePath(slavePath, Constants.PATH_SEPARATOR + ip); if(znodeApi.checkExists(client, infoPath)){ readyIpLst.add(ip); } } //向所有的slave机器分配任务 int jobSize = groupJobMap.entrySet().size(); int slaveSize = readyIpLst.size(); int perSlaveJobSize = jobSize / slaveSize; int i = 0; for (Map.Entry<String, List<String>> entry : groupJobMap.entrySet()) { i++; String ip = null; // 大于零,均分到所有slave机器上;小于零,分到一台机器上 if (perSlaveJobSize > 0) { ip = readyIpLst.get(i / perSlaveJobSize); } else { ip = readyIpLst.get(0); } String slaveJobPath = ZKPaths.makePath(slavePath, Constants.PATH_SEPARATOR + ip, Constants.EJOB_SERVER_NODE_SLAVE_EXECUTION, Constants.PATH_SEPARATOR + entry.getKey(), Constants.PATH_SEPARATOR + entry.getValue()); znodeApi.createPersistent(client, slaveJobPath, null); } return true; } @Override public List<String> getAllJobNameByGroup(CuratorFramework client, String path) { return znodeApi.getChildren(client, path); } @Override public List<EjobServerInfo> getServerInfos(){ List<EjobServerInfo> serverLst = new ArrayList<EjobServerInfo>(); CuratorFramework client = threadLocalClient.getCuratorClient().getCuratorClient(); String slavePath = ZKPaths.makePath(Constants.ROOT, Constants.EJOB_SERVER_NODE_ROOT, Constants.EJOB_SERVER_NODE_SLAVE); String masterHostPath = Constants.EJOB_SERVER_NODE_MASTER_IP; String masterIp =""; try { masterIp = SlaveUtils.getLeaderLatch().getLeader().getId(); } catch (Exception e) { LoggerUtil.error("get master by leaderLatch ERROR",e); } // String masterIp = znodeApi.getData(client, masterHostPath); List<String> slaveIpLst = znodeApi.getChildren(client, slavePath); for (String slaveIp : slaveIpLst) { EjobServerInfo serverInfo = new EjobServerInfo(slaveIp); String ipPath = ZKPaths.makePath(slavePath, Constants.PATH_SEPARATOR + slaveIp); String hostNamePath = ZKPaths.makePath(ipPath, Constants.EJOB_SERVER_NODE_SLAVE_HOSTNAME); String statusPath = znodeApi.makePath(ipPath, Constants.EJOB_SERVER_NODE_SLAVE_STATUS); serverInfo.setHostName(znodeApi.getData(client, hostNamePath)); if (slaveIp.equals(masterIp)) { serverInfo.setMaster(true); } else { serverInfo.setMaster(false); } if(znodeApi.checkExists(client, statusPath)){ serverInfo.setActive(true); } else { serverInfo.setActive(false); } serverLst.add(serverInfo); } return serverLst; } @Override public Map<String, List<String>> getServerJob(EjobServerInfo server){ Map<String, List<String>> groupJobMap = new HashMap<String, List<String>>(); if(server == null){ return groupJobMap; } CuratorFramework client = threadLocalClient.getCuratorClient().getCuratorClient(); String slavePath = ZKPaths.makePath(Constants.ROOT, Constants.EJOB_SERVER_NODE_ROOT, Constants.EJOB_SERVER_NODE_SLAVE); String slaveServerPath = ZKPaths.makePath(slavePath, Constants.PATH_SEPARATOR + server.getIp()); String slavePathExecution = ZKPaths.makePath(slaveServerPath, Constants.EJOB_SERVER_NODE_SLAVE_EXECUTION); List<String> groupLst = znodeApi.getChildren(client, slavePathExecution); for(String groupName : groupLst){ String slavePathJob = ZKPaths.makePath(slavePathExecution, Constants.PATH_SEPARATOR + groupName); String jobNameStr = znodeApi.getData(client, slavePathJob); if(StringUtils.isNoneBlank(jobNameStr)){ String [] jobNameArray = jobNameStr.split(Constants.TRANSFER_CHAR + Constants.JOB_SEPARATOR); List<String> jobNameLst = new ArrayList<String>(); for(String jobName : jobNameArray){ jobNameLst.add(jobName); } groupJobMap.put(groupName, jobNameLst); } } return groupJobMap; } @Override public HURL getHurlByJobAndIp(String group, String jobName, final String ip) { CuratorFramework client = threadLocalClient.getCuratorClient().getCuratorClient(); String slavePath = ZKPaths.makePath(Constants.ROOT, Constants.EJOB_RPC_NODE_ROOT, Constants.PATH_SEPARATOR+group,Constants.PATH_SEPARATOR+jobName,Constants.PATH_SEPARATOR+Constants.EJOB_PROVIDERS); List<String> list = znodeApi.getChildren(client, slavePath); //String hostIp = ""; HURL result = null; for(String ipPort:list){ if(ipPort.indexOf(ip)>-1){ //hostIp = ip; String hurl = znodeApi.getData(client, slavePath+Constants.PATH_SEPARATOR+ipPort); result = HURL.valueOf(hurl); break; } } return result; } @Override public Job getJobByGroupNameAndJobName(String group, String jobName) { if(StringUtils.isEmpty(group) && StringUtils.isEmpty(jobName)){ throw new RuntimeException("group name or job name is empty"); } CuratorFramework client = threadLocalClient.getCuratorClient().getCuratorClient(); String jobPath = znodeApi.makePath(Constants.ROOT, Constants.APP_JOB_NODE_ROOT,Constants.PATH_SEPARATOR+group,Constants.PATH_SEPARATOR+jobName, Constants.APP_JOB_NODE_CONFIG); String data = znodeApi.getData(client, jobPath); Job job = new Job(); if(StringUtils.isNoneBlank(data)){ job = new Gson().fromJson(data, Job.class); return job; }else{ return null; } } @Override public List<String> getSessionsList() { List<String> sessionList = Lists.newArrayList(); CuratorFramework client = threadLocalClient.getCuratorClient().getCuratorClient(); String sessionRootPath = Constants.EJOB_SERVER_NODE_SESSION; List<String> sessionNames = znodeApi.getChildren(client, sessionRootPath); for(String session : sessionNames){ String sessionPath = znodeApi.makePath(Constants.EJOB_SERVER_NODE_SESSION, session); if(!znodeApi.getChildren(client, sessionPath).isEmpty()){ sessionList.add(session); } } return sessionList; } }