Search in sources :

Example 11 with DockerStatus

use of com.chinaunicom.rundocker.bean.DockerStatus in project mesosFramework by zhizuqiu.

the class EtcdService method setStatusAtomic.

/**
 * 设置任务状态,当状态更新时间 < etcd节点的时间
 *
 * @param logTime   任务标识
 * @param jobStatus jobStatus
 * @return 成功与否
 */
public SetResult setStatusAtomic(Long logTime, DockerStatus jobStatus) {
    String key = AppDataStore.getConfig().getFrameworkName() + JOBSTATUS_PATH + Tools.getStringByJsonpathRecursion(jobStatus.getId().replaceAll("/", "."));
    DockerStatus jobStatusTemp = null;
    boolean getSuccess = false;
    Integer modifiedIndex = null;
    /*
         * JsonSyntaxException|ClientException表示节点异常,可以直接覆盖
         * ServerException|Exception表示未知异常,需要同步程序处理
        */
    try {
        ResponseNode responseNode = etcd.getKey(key);
        if (EtcdAction.GET.equals(responseNode.getAction())) {
            jobStatusTemp = new Gson().fromJson(responseNode.getNode().getValue(), DockerStatus.class);
            modifiedIndex = responseNode.getNode().getModifiedIndex();
            getSuccess = true;
        }
    } catch (JsonSyntaxException e) {
        logger.error("[" + logTime + "]" + "setNodeAtomic->fromJson->JsonSyntaxException->" + e.getMessage());
        getSuccess = true;
    } catch (ClientException e) {
        logger.error("[" + logTime + "]" + "setNodeAtomic->getKey->ClientException->" + e.getDetail().getMessage());
        getSuccess = true;
    } catch (ServerException e) {
        logger.error("[" + logTime + "]" + "setNodeAtomic->getKey->ServerException->" + e.getDetail().getMessage());
        return HAS_EXCEPTION;
    } catch (Exception e) {
        logger.error("[" + logTime + "]" + "setNodeAtomic->getKey->Exception->" + e.getMessage());
        return HAS_EXCEPTION;
    }
    if (!getSuccess) {
        return HAS_EXCEPTION;
    }
    // 如果状态更新时间<etcd节点的时间,不更新
    if (jobStatusTemp != null) {
        Double timestampTemp = jobStatusTemp.getTimestamp();
        if (timestampTemp != null) {
            Double timestamp = jobStatus.getTimestamp();
            if (timestamp < timestampTemp) {
                return UNNECESSARY;
            }
        }
    }
    boolean setSuccess = false;
    try {
        ResponseNodeAndPrevnode responseNodeAndPrevnode;
        if (modifiedIndex != null) {
            responseNodeAndPrevnode = etcd.setKeyAtomic(key, new Gson().toJson(jobStatus), String.valueOf(modifiedIndex));
        } else {
            responseNodeAndPrevnode = etcd.setKey(key, new Gson().toJson(jobStatus));
        }
        if (EtcdAction.COMPARE_AND_SWAP.equals(responseNodeAndPrevnode.getAction())) {
            setSuccess = true;
        }
    } catch (ClientException e) {
        logger.error("[" + logTime + "]" + "setNodeAtomic->setKeyAtomic->ClientException->" + e.getDetail().getMessage());
        return HAS_EXCEPTION;
    } catch (ServerException e) {
        logger.error("[" + logTime + "]" + "setNodeAtomic->setKeyAtomic->ServerException->" + e.getDetail().getMessage());
        return HAS_EXCEPTION;
    } catch (Exception e) {
        logger.error("[" + logTime + "]" + "setNodeAtomic->setKeyAtomic->Exception->" + e.getMessage());
        return HAS_EXCEPTION;
    }
    return setSuccess ? SUCCESS : HAS_EXCEPTION;
}
Also used : ResponseNodeAndPrevnode(com.chinaunicom.etcd.v2.model.ResponseNodeAndPrevnode) ResponseNode(com.chinaunicom.etcd.v2.model.ResponseNode) JsonSyntaxException(com.google.gson.JsonSyntaxException) ServerException(com.chinaunicom.etcd.v2.exception.ServerException) DockerStatus(com.chinaunicom.rundocker.bean.DockerStatus) Gson(com.google.gson.Gson) ClientException(com.chinaunicom.etcd.v2.exception.ClientException) JsonSyntaxException(com.google.gson.JsonSyntaxException) ClientException(com.chinaunicom.etcd.v2.exception.ClientException) ServerException(com.chinaunicom.etcd.v2.exception.ServerException)

Example 12 with DockerStatus

use of com.chinaunicom.rundocker.bean.DockerStatus in project mesosFramework by zhizuqiu.

the class DockerScheduler method resourceOffers.

@Override
public void resourceOffers(SchedulerDriver schedulerDriver, List<Offer> offers) {
    // logger.info("[" + logTime + "]"+"----------------------------------");
    // logger.info("[" + logTime + "]"+"offers.size(): " + offers.size());
    // 时间戳
    Long logTime = System.currentTimeMillis();
    // 真正需要下发的任务列表
    List<DockerJob> pendingJobs = new ArrayList<>();
    for (String key : AppDataStore.jobsKeySet()) {
        DockerJob job = AppDataStore.jobsGet(key);
        DockerStatus jobStatus = AppDataStore.statusGet(key);
        if (jobStatus != null) {
            // 下发条件:1.没有提交,2.依赖都运行,3.满足重试时间间隔
            if (!jobStatus.getSubmitted() && SchedulerService.hasRunDependencies(job) && SchedulerService.hasSatisfyRetryInterval(job, jobStatus)) {
                pendingJobs.add(job);
            }
        }
    }
    // 遍历offers
    for (Offer offer : offers) {
        logger.info("[" + logTime + "]" + "----------------------");
        logger.info("[" + logTime + "]" + "offer hostname: " + offer.getHostname());
        logger.info("[" + logTime + "]" + "----------------------");
        logger.info("[" + logTime + "]" + offer);
        // 如果待下发的任务列表不为空
        if (!pendingJobs.isEmpty()) {
            // 存储并处理offer资源的工具类
            OfferTemp offerTemp = new OfferTemp(offer);
            DockerJob jobOld = pendingJobs.get(0);
            DockerJob dockerJob = SchedulerService.getRealDockerJob(jobOld);
            DockerStatus jobStatus = AppDataStore.statusGet(dockerJob.getKey());
            // 匹配约束
            List<List<String>> constraints = dockerJob.getConstraints();
            Boolean matchConstraints = SchedulerService.matchConstraints(offer, constraints);
            if (!matchConstraints) {
                logger.info("[" + logTime + "]" + "------------");
                logger.info("[" + logTime + "]" + "not match constraints");
                schedulerDriver.declineOffer(offer.getId());
                continue;
            }
            // 匹配usePreHost
            Boolean matchPreHost = SchedulerService.matchUsePreHost(offer, dockerJob, jobStatus);
            if (!matchPreHost) {
                logger.info("[" + logTime + "]" + "------------");
                logger.info("[" + logTime + "]" + "not match preHost");
                schedulerDriver.declineOffer(offer.getId());
                continue;
            }
            // 匹配资源
            if (!offerTemp.acceptTask(dockerJob)) {
                logger.info("[" + logTime + "]" + "------------");
                logger.info("[" + logTime + "]" + "not accept task with resource");
                schedulerDriver.declineOffer(offer.getId());
                continue;
            }
            // 上面是下发前的检查工作
            // 要接受的offer id列表
            List<OfferID> offerIds = new ArrayList<>();
            // 要进行操作的列表
            List<Offer.Operation> operations = new ArrayList<>();
            logger.info("[" + logTime + "]" + "------------");
            logger.info("[" + logTime + "]" + "persistenceStatus is " + jobStatus.get_persistenceInfo().getPersistenceStatus());
            switch(jobStatus.get_persistenceInfo().getPersistenceStatus()) {
                case NONE:
                    break;
                case NEW:
                    // 预留资源
                    Resource resourceReserve = SchedulerService.buildReserveResource(dockerJob);
                    if (resourceReserve == null) {
                        logger.error("[" + logTime + "]" + "buildReserveResource() error");
                        schedulerDriver.declineOffer(offer.getId());
                        continue;
                    } else {
                        // 添加到operations中
                        operations.add(Offer.Operation.newBuilder().setType(Offer.Operation.Type.RESERVE).setReserve(Offer.Operation.Reserve.newBuilder().addResources(resourceReserve).build()).build());
                    }
                    // 持久卷
                    Resource resource = SchedulerService.buildCreateResource(dockerJob);
                    if (resource == null) {
                        logger.error("[" + logTime + "]" + "buildCreateResource() error");
                        schedulerDriver.declineOffer(offer.getId());
                        continue;
                    } else {
                        // 添加到operations中
                        operations.add(Offer.Operation.newBuilder().setType(Offer.Operation.Type.CREATE).setCreate(Offer.Operation.Create.newBuilder().addVolumes(resource).build()).build());
                    }
                    // 持久卷重复创建并不会导致任务启动失败,但是会导致多预留一块资源
                    jobStatus.get_persistenceInfo().setPersistenceStatus(DockerStatus.PersistenceStatus.TRY_TO_RESERVE_AND_CREATE);
                    jobStatus.get_persistenceInfo().setPersistenceAgentid(offer.getSlaveId().getValue());
                    // 更新etcd
                    etcdService.setStatusAtomic(logTime, jobStatus);
                    break;
                case TRY_TO_RESERVE_AND_CREATE:
                case END:
                    // todo 检查持久卷
                    logger.info("检查持久卷");
                    Boolean matchPersistentVolumes = SchedulerService.matchPersistentVolumes(offer, dockerJob);
                    if (!matchPersistentVolumes) {
                        logger.info("[" + logTime + "]" + "------------");
                        logger.info("[" + logTime + "]" + "not match persistent volumes");
                        schedulerDriver.declineOffer(offer.getId());
                        continue;
                    }
                    break;
                default:
            }
            // 准备要Launch的任务
            TaskInfo task;
            try {
                task = SchedulerService.buildTaskInfo(offer, dockerJob);
            } catch (Exception e) {
                logger.error("[" + logTime + "]" + "job id " + dockerJob.getId() + " buildTaskInfo Exception:" + e.getMessage());
                schedulerDriver.declineOffer(offer.getId());
                etcdService.recordException(e);
                continue;
            }
            logger.info("[" + logTime + "]" + "------------");
            logger.info("[" + logTime + "]" + "taskInfo: " + task.getName());
            // 添加到operations中
            operations.add(Offer.Operation.newBuilder().setType(Offer.Operation.Type.LAUNCH).setLaunch(Offer.Operation.Launch.newBuilder().addTaskInfos(TaskInfo.newBuilder(task))).build());
            // 修改任务状态
            jobStatus.setHostname(offer.getHostname());
            jobStatus.launch();
            jobStatus.setCurrentTime();
            jobStatus.setSlaveId(offer.getSlaveId().getValue());
            // 设置confMap
            jobStatus.set_confMap(jobOld.getEnvConfMap());
            // 更新etcd中的任务状态
            EtcdService.SetResult setResult = etcdService.setStatusAtomic(logTime, jobStatus);
            switch(setResult) {
                case HAS_EXCEPTION:
                    // todo 触发同步状态方法
                    break;
                default:
                    break;
            }
            logger.info("[" + logTime + "]" + "resourceOffers->setStatusAtomic:" + setResult);
            // 把将要下发的任务从待下发任务列表中删除
            pendingJobs.remove(0);
            // 接受offer
            offerIds.add(offer.getId());
            // declineOffer时的过滤器
            Filters filters = Filters.newBuilder().setRefuseSeconds(1).build();
            Status status = schedulerDriver.acceptOffers(offerIds, operations, filters);
            logger.info("[" + logTime + "]" + "acceptOffers:" + status);
        } else {
            // 如果待下发的任务列表为空,拒绝offer
            schedulerDriver.declineOffer(offer.getId());
        // logger.info("[" + logTime + "]"+"------------");
        // logger.info("[" + logTime + "]"+"declineOffer :" + offer.getId());
        }
    }
    if (pendingJobs.isEmpty()) {
        // 判断是否所有任务已下发,是不需要接受offer
        if (SchedulerService.checkAllAppsIsAccept()) {
            schedulerDriver.suppressOffers();
            logger.info("suppressOffers");
        }
    }
}
Also used : DockerStatus(com.chinaunicom.rundocker.bean.DockerStatus) ArrayList(java.util.ArrayList) OfferTemp(com.chinaunicom.rundocker.service.OfferTemp) DockerJob(com.chinaunicom.rundocker.bean.DockerJob) EtcdService(com.chinaunicom.rundocker.service.EtcdService) DockerStatus(com.chinaunicom.rundocker.bean.DockerStatus) ArrayList(java.util.ArrayList) List(java.util.List)

Example 13 with DockerStatus

use of com.chinaunicom.rundocker.bean.DockerStatus in project mesosFramework by zhizuqiu.

the class Tools method getObjFromStatusUseJsonPath.

/**
 * 使用jsonPath工具,获取status的json里面的值
 *
 * @param id       appid
 * @param operator jsonPath参数
 * @return 值
 */
public static Object getObjFromStatusUseJsonPath(String id, String operator) {
    if (id == null || id.trim().isEmpty()) {
        return null;
    }
    String key = Tools.getStringByJsonpathRecursion(id.trim().replaceAll("/", "."));
    DockerStatus dockerStatus = AppDataStore.statusGet(key);
    if (dockerStatus == null) {
        return null;
    }
    if (operator == null || operator.trim().isEmpty()) {
        return dockerStatus;
    }
    Object obj = null;
    try {
        String json = new Gson().toJson(dockerStatus);
        obj = JsonPath.read(json, operator);
    } catch (Exception e) {
        logger.error(e.getMessage());
    }
    return obj;
}
Also used : DockerStatus(com.chinaunicom.rundocker.bean.DockerStatus)

Example 14 with DockerStatus

use of com.chinaunicom.rundocker.bean.DockerStatus in project mesosFramework by zhizuqiu.

the class AppDataStore method getJobAndStatusTemp.

// ------------
public static JobAndStatusTemp getJobAndStatusTemp(String key) {
    DockerJob dockerJob = jobsGet(key);
    if (dockerJob == null) {
        return null;
    }
    DockerStatus dockerStatus = statusGet(key);
    if (dockerStatus == null) {
        return null;
    }
    return new JobAndStatusTemp(key, dockerJob, dockerStatus);
}
Also used : DockerStatus(com.chinaunicom.rundocker.bean.DockerStatus) DockerJob(com.chinaunicom.rundocker.bean.DockerJob)

Example 15 with DockerStatus

use of com.chinaunicom.rundocker.bean.DockerStatus in project mesosFramework by zhizuqiu.

the class EtcdServiceTest method putJobsAndStatusTest.

@Test
public void putJobsAndStatusTest() {
    String id = "/2048/1";
    DockerJob job = new DockerJob();
    job.setId(id);
    DockerStatus dockerStatus = new DockerStatus();
    dockerStatus.setId(id);
    String id2 = "/2048/2";
    DockerJob job2 = new DockerJob();
    job2.setId(id2);
    DockerStatus dockerStatus2 = new DockerStatus();
    dockerStatus2.setId(id2);
    AppDataStore.JobAndStatusTemp jobAndStatusTemp = new AppDataStore.JobAndStatusTemp(id, job, dockerStatus);
    AppDataStore.JobAndStatusTemp jobAndStatusTemp2 = new AppDataStore.JobAndStatusTemp(id2, job2, dockerStatus2);
    // put两个值
    AppDataStore.JobAndStatusTemp jobAndStatusTempResult = AppDataStore.postJobsAndStatus(jobAndStatusTemp);
    AppDataStore.JobAndStatusTemp jobAndStatusTempResult2 = AppDataStore.postJobsAndStatus(jobAndStatusTemp2);
    System.out.println(AppDataStore.jobsGet());
    System.out.println(AppDataStore.statusGet());
    System.out.println("------------");
    // 回滚1值
    AppDataStore.postJobsAndStatus(jobAndStatusTempResult);
    System.out.println(AppDataStore.jobsGet());
    System.out.println(AppDataStore.statusGet());
    System.out.println("------------");
    // 回滚2值
    AppDataStore.postJobsAndStatus(jobAndStatusTempResult2);
    System.out.println(AppDataStore.jobsGet());
    System.out.println(AppDataStore.statusGet());
}
Also used : DockerStatus(com.chinaunicom.rundocker.bean.DockerStatus) AppDataStore(com.chinaunicom.rundocker.store.AppDataStore) DockerJob(com.chinaunicom.rundocker.bean.DockerJob) Test(org.junit.Test)

Aggregations

DockerStatus (com.chinaunicom.rundocker.bean.DockerStatus)16 DockerJob (com.chinaunicom.rundocker.bean.DockerJob)9 Task (com.chinaunicom.rundocker.bean.returnparm.Task)3 EtcdService (com.chinaunicom.rundocker.service.EtcdService)3 Gson (com.google.gson.Gson)3 ArrayList (java.util.ArrayList)3 Protos (org.apache.mesos.Protos)3 ResponseNode (com.chinaunicom.etcd.v2.model.ResponseNode)2 AppDataStore (com.chinaunicom.rundocker.store.AppDataStore)2 JsonSyntaxException (com.google.gson.JsonSyntaxException)2 Test (org.junit.Test)2 ClientException (com.chinaunicom.etcd.v2.exception.ClientException)1 ServerException (com.chinaunicom.etcd.v2.exception.ServerException)1 Node (com.chinaunicom.etcd.v2.model.Node)1 ResponseNodeAndPrevnode (com.chinaunicom.etcd.v2.model.ResponseNodeAndPrevnode)1 HostAndPort (com.chinaunicom.rundocker.bean.HostAndPort)1 Jobs (com.chinaunicom.rundocker.bean.returnparm.Jobs)1 MesosService (com.chinaunicom.rundocker.service.MesosService)1 OfferTemp (com.chinaunicom.rundocker.service.OfferTemp)1 Config (com.chinaunicom.rundocker.store.Config)1