All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.schedulerx.worker.master.StandaloneTaskMaster Maven / Gradle / Ivy

There is a newer version: 1.12.2
Show newest version
package com.alibaba.schedulerx.worker.master;

import java.io.IOException;
import java.util.List;

import com.alibaba.schedulerx.common.domain.InstanceStatus;
import com.alibaba.schedulerx.common.domain.JobInstanceInfo;
import com.alibaba.schedulerx.common.domain.TaskStatus;
import com.alibaba.schedulerx.common.domain.TimeType;
import com.alibaba.schedulerx.common.util.ConfigUtil;
import com.alibaba.schedulerx.common.util.IdUtil;
import com.alibaba.schedulerx.common.util.JobUtil;
import com.alibaba.schedulerx.common.util.JsonUtil;
import com.alibaba.schedulerx.protocol.Worker;
import com.alibaba.schedulerx.protocol.Worker.MasterDestroyContainerPoolRequest;
import com.alibaba.schedulerx.protocol.Worker.MasterStartContainerRequest;
import com.alibaba.schedulerx.protocol.Worker.MasterStartContainerResponse;
import com.alibaba.schedulerx.protocol.utils.FutureUtils;
import com.alibaba.schedulerx.worker.SchedulerxWorker;
import com.alibaba.schedulerx.worker.domain.JavaProcessorProfile;
import com.alibaba.schedulerx.worker.domain.WorkerConstants;
import com.alibaba.schedulerx.worker.log.LogFactory;
import com.alibaba.schedulerx.worker.log.Logger;
import com.alibaba.schedulerx.worker.logcollector.ClientLoggerMessage;
import com.alibaba.schedulerx.worker.logcollector.LogCollector;
import com.alibaba.schedulerx.worker.logcollector.LogCollectorFactory;
import com.alibaba.schedulerx.worker.processor.MapJobProcessor;
import com.alibaba.schedulerx.worker.route.Router;
import com.alibaba.schedulerx.worker.route.RouterFactory;
import com.alibaba.schedulerx.worker.util.ActorPathUtil;
import com.alibaba.schedulerx.worker.util.JobProcessorUtil;
import com.alibaba.schedulerx.worker.util.WorkerIdGenerator;
import com.google.common.collect.Lists;

import akka.actor.ActorContext;
import akka.actor.ActorSelection;


/**
 *
 * @author xiaomeng.hxm
 */
public class StandaloneTaskMaster extends TaskMaster {

    private LogCollector logCollector = LogCollectorFactory.get();
    private static final Logger LOGGER = LogFactory.getLogger(StandaloneTaskMaster.class);

    private ActorSelection currentSelection = null;

    private String currentWorkerAddr = null;

    public StandaloneTaskMaster(JobInstanceInfo jobInstanceInfo, ActorContext actorContext) throws Exception {
        super(jobInstanceInfo, actorContext);
        currentSelection = getActorContext().actorSelection(getLocalContainerRouterPath());
        this.currentWorkerAddr = this.getLocalWorkerIdAddr();
    }

    /**
     * Standalone TaskMaster only submit to localhost
     */
    @Override
    public synchronized void submitInstance(JobInstanceInfo info) {
        long taskId = aquireTaskId();
        String uniqueId = IdUtil.getUniqueId(info.getJobId(), info.getJobInstanceId(), taskId);
        MasterStartContainerRequest.Builder builder = convert2StartContainerRequestBuilder(info, taskId);
        MasterStartContainerRequest request = builder.build();
        try {
            // 如果秒级别任务开启了任务执行分发,则轮询选取执行机器
            Boolean dispatch = ConfigUtil.getWorkerConfig().getBoolean(WorkerConstants.SECOND_DELAY_STANDALONE_DISPATCH,
                    WorkerConstants.SECOND_DELAY_STANDALONE_DISPATCH_DEFAULT);
            if(JobUtil.isSecondTypeJob(TimeType.parseValue(jobInstanceInfo.getTimeType())) && dispatch){
                this.currentWorkerAddr = selectWorker();
                currentSelection = getActorContext().actorSelection(ActorPathUtil.getContainerRouterPath(selectWorker()));
            }
            MasterStartContainerResponse response = (MasterStartContainerResponse) FutureUtils.awaitResult(currentSelection, request, 10);
            if (response.getSuccess()) {
                taskStatusMap.put(uniqueId, TaskStatus.INIT);
//                logCollector.collect(uniqueId, ClientLoggerMessage.STANDALONE_INSTANCE_INIT_SUCCESS);
            } else {
                LOGGER.error("submitTask error.", response.getMessage());
                taskStatusMap.put(uniqueId, TaskStatus.FAILED);
                logCollector.collect(jobInstanceInfo.getAppGroupId(), uniqueId, ClientLoggerMessage.appendMessage(ClientLoggerMessage.STANDALONE_INSTANCE_INIT_FAIL,
                        response.getMessage()), jobInstanceInfo.getGroupId());
                Worker.ContainerReportTaskStatusRequest faileRequest = Worker.ContainerReportTaskStatusRequest.newBuilder()
                        .setJobId(info.getJobId())
                        .setJobInstanceId(info.getJobInstanceId())
                        .setTaskId(taskId)
                        .setStatus(TaskStatus.FAILED.getValue())
                        .setResult("Start container request failed: " + response.getMessage())
                        .setWorkerId(WorkerIdGenerator.get())
                        .setWorkerAddr(SchedulerxWorker.WORKER_ADDR)
                        .setSerialNum(getSerialNum())
                        .build();
                this.updateTaskStatus(faileRequest);
                return;
            }
            init();
        } catch (Throwable e) {
            LOGGER.error("submitTask error.", e);
            logCollector.collect(jobInstanceInfo.getAppGroupId(), uniqueId, ClientLoggerMessage.STANDALONE_INSTANCE_INIT_FAIL, e, jobInstanceInfo.getGroupId());
            taskStatusMap.put(uniqueId, TaskStatus.FAILED);
            Worker.ContainerReportTaskStatusRequest faileRequest = Worker.ContainerReportTaskStatusRequest.newBuilder()
                    .setJobId(info.getJobId())
                    .setJobInstanceId(info.getJobInstanceId())
                    .setTaskId(taskId)
                    .setStatus(TaskStatus.FAILED.getValue())
                    .setResult("SubmitTask error. "+e.getMessage())
                    .setWorkerId(WorkerIdGenerator.get())
                    .setWorkerAddr(SchedulerxWorker.WORKER_ADDR)
                    .setSerialNum(getSerialNum())
                    .build();
            this.updateTaskStatus(faileRequest);
        }
    }

    /**
     * 轮询获取可执行机器
     * @return
     */
    protected String selectWorker() {
        String workerAddr = null;
        if (jobInstanceInfo.getRouteStrategyType() == null ||
            jobInstanceInfo.getRouteStrategyContent() == null ||
            jobInstanceInfo.getTargetWorkerAddrsMap() == null) {
            List allWorkers = jobInstanceInfo.getAllWorkers();
            int size = allWorkers.size();
            int index = 0;
            if (size == 0) {
                return null;
            } else if (getSerialNum() >= size) {
                index = new Long(getSerialNum() % size).intValue();
            }
            workerAddr = allWorkers.get(index);
        } else {
            Router router = RouterFactory.getRouter(jobInstanceInfo.getAppGroupId(), jobInstanceInfo.getJobId(),
                    jobInstanceInfo.getRouteStrategyType(), jobInstanceInfo.getRouteStrategyContent());

            workerAddr = router.route(jobInstanceInfo.getAppGroupId(), jobInstanceInfo.getJobId(),
                    jobInstanceInfo.getAllWorkers(), jobInstanceInfo.getTargetWorkerAddrsMap(), getSerialNum(), this.getLocalWorkerIdAddr());
        }
        LOGGER.info("dispatcher workerAddr is " + workerAddr);
        return workerAddr;
    }

    @Override
    public synchronized void killInstance(boolean mayInterruptIfRunning, String reason) {
        super.killInstance(mayInterruptIfRunning, reason);
        this.sendKillContainerRequest(mayInterruptIfRunning, Lists.newArrayList(this.currentWorkerAddr));
        updateNewInstanceStatus(getSerialNum(), jobInstanceInfo.getJobInstanceId(), InstanceStatus.FAILED, reason);
        if(!instanceStatus.isFinish()){
            instanceStatus = InstanceStatus.FAILED;
        }
    }

    @Override
    public synchronized void destroyContainerPool() {
        try {
            MasterDestroyContainerPoolRequest request = MasterDestroyContainerPoolRequest.newBuilder()
                .setJobInstanceId(jobInstanceInfo.getJobInstanceId())
                .setSerialNum(getSerialNum())
                .build();
            FutureUtils.awaitResult(currentSelection, request, 5);
        } catch (Throwable e) {
            LOGGER.error("destroy containerPool failed", e);
        }
    }

    @Override
    protected void checkProcessor() throws Exception {
        if ("java".equalsIgnoreCase(jobInstanceInfo.getJobType())) {
            JavaProcessorProfile profile = JsonUtil.fromJson(jobInstanceInfo.getContent(), JavaProcessorProfile.class);
            if (JobProcessorUtil.checkJavaProcessor(profile.getClassName(), MapJobProcessor.class)) {
                throw new IOException(profile.getClassName() + " shouldn't extends MapJobProcessor or MapReduceJobProcessor");
            }
        }
    }

    public ActorSelection getCurrentSelection() {
        return currentSelection;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy