datax源碼閱讀二:Engine流程

一、根據前面python文件知道,java的main函數是com.alibaba.datax.core.Engine

  public static void main(String[] args) throws Exception {
    int exitCode = 0;
    try {
        Engine.entry(args);
    } catch (Throwable e) {
        exitCode = 1;
        String trace = ExceptionTracker.trace(e);
        String errDesc = "未知datax錯誤,參考堆棧內容分析。";
        LOG.error("\n\n經DataX智能分析,該任務最可能的錯誤原因是:\n" + trace);
        if (e instanceof DataXException) {
            DataXException tempException = (DataXException) e;
            ErrorCode errorCode = tempException.getErrorCode();
            errDesc = errorCode.getDescription();
            if (errorCode instanceof FrameworkErrorCode) {
                FrameworkErrorCode tempErrorCode = (FrameworkErrorCode) errorCode;
                exitCode = tempErrorCode.toExitValue();
            }
        }
        System.exit(exitCode);
    }
    System.exit(exitCode);
}

main函數主要catch了一下異常,並將異常信息打印出來,實際執行在entry函數中

  public static void entry(final String[] args) throws Throwable {
    Options options = new Options();
    options.addOption("job", true, "Job config.");
    options.addOption("jobid", true, "Job unique id.");
    options.addOption("mode", true, "Job runtime mode.");

    BasicParser parser = new BasicParser();
    CommandLine cl = parser.parse(options, args);

    String jobPath = cl.getOptionValue("job");

    // 如果用戶沒有明確指定jobid, 則 datax.py 會指定 jobid 默認值爲-1
    String jobIdString = cl.getOptionValue("jobid");
    RUNTIME_MODE = cl.getOptionValue("mode");

    Configuration configuration = ConfigParser.parse(jobPath);

    long jobId;
    if (!"-1".equalsIgnoreCase(jobIdString)) {
        jobId = Long.parseLong(jobIdString);
    } else {
        // only for dsc & ds & datax 3 update
        String dscJobUrlPatternString = "/instance/(\\d{1,})/config.xml";
        String dsJobUrlPatternString = "/inner/job/(\\d{1,})/config";
        String dsTaskGroupUrlPatternString = "/inner/job/(\\d{1,})/taskGroup/";
        List<String> patternStringList = Arrays.asList(dscJobUrlPatternString,
                dsJobUrlPatternString, dsTaskGroupUrlPatternString);
        jobId = parseJobIdFromUrl(patternStringList, jobPath);
    }

    boolean isStandAloneMode = "standalone".equalsIgnoreCase(RUNTIME_MODE);
    if (!isStandAloneMode && jobId == -1) {
        // 如果不是 standalone 模式,那麼 jobId 一定不能爲-1
        throw DataXException.asDataXException(FrameworkErrorCode.CONFIG_ERROR, "非 standalone 模式必須在 URL 中提供有效的 jobId.");
    }
    configuration.set(CoreConstant.DATAX_CORE_CONTAINER_JOB_ID, jobId);

    //打印vmInfo
    VMInfo vmInfo = VMInfo.getVmInfo();
    if (vmInfo != null) {
        LOG.info(vmInfo.toString());
    }

    LOG.info("\n" + Engine.filterJobConfiguration(configuration) + "\n");

    LOG.debug(configuration.toJSON());

    ConfigurationValidate.doValidate(configuration);
    Engine engine = new Engine();
    engine.start(configuration);
}

entry函數主要功能:

1、解析了java命令行的三個參數,分別是job、jobid和mode,其中job是用戶配置的json文件路徑,jobid和mode是python文件帶進來的,單機模式下可以忽略改參數
2、讀取用戶配置的json文件,轉化爲內部的configuration配置
3、打印相關信息,並校驗json文件的合法性
4、啓動engine執行

entry執行完畢之後,進入start函數,關鍵代碼如下:

 public void start(Configuration allConf) {
    // 綁定column轉換信息
    ColumnCast.bind(allConf);
    /**
     * 初始化PluginLoader,可以獲取各種插件配置
     */
    LoadUtil.bind(allConf);
    *************
     container = new JobContainer(allConf);
    *************
    container.start();
}

start函數中主要包括:

1、列轉換默認值,即動態在configuration中注入默認值
2、初始化插件的LoadUtil,後面classLoader相關操作都會依賴這個函數
3、初始化JobContainer並啓動
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章