前言
在上一篇文章当中我们已经了解了datax的启动原理,以及datax的最基础的配置,datax底层java启动类的入口及关键参数。
接下来我将进行启动类执行的源码分析,设计到datax当中的一些关键的配置文件的初始化,各种组件之间的加载原理及运行原理,带领大家深度理解datax的底层运行逻辑。
一、加载配置文件
在上一篇我们已经知道了,datax的调用的是Engine类的mian方法,代码当中只有一行关键代码Engine.entry(args)。
public static void main(String[] args) throws Exception {
//我们人为设置的启动参数
args = new String[]{
"-mode", "standalone",
"-jobid", "-1",
"-job", "D:\\chrom下载\\datax\\datax\\bin\\mysql2mysql.json"
};
//设置datax的解压目录
System.setProperty("datax.home", "D:\\chrom下载\\datax\\datax");
int exitCode = 0;
try {
//所有的逻辑都在这类方法里面
Engine.entry(args);
} catch (Throwable e) {
//异常处理省略。。。
}
System.exit(exitCode);
}
- Engine.entry(args)核心入口方法,该方法最核心内容主要是解析datax运行所需的所有的参数,将其封装成Configuration,后续调用engine.start(configuration) 进行所有的业务逻辑的处理。我们需要着重的关注的方法只有一个就是
Configuration configuration = ConfigParser.parse(jobPath)
public static void entry(final String[] args) throws Throwable {
//省略不重要代码。。。
//核心的解析逻辑,我们需要特别关注的代码逻辑
Configuration configuration = ConfigParser.parse(jobPath);
//省略不重要代码。。。
ConfigurationValidate.doValidate(configuration);
Engine engine = new Engine();
engine.start(configuration);
}
- 解析我们需要的配置文件,job任务的json配置文件mysql2mysql.json,{you datax path}/conf/core.json文件,遍历{you datax patch}/plugin/reader/下的所有reade和{you datax patch}/plugin/writer/下的所有writer,加载符合的reader/writer的配置的plugin.json文件,reader/writer配置就是在mysql2mysql.json当中配置的,需要注意我们配置的reader/writer名称必须和reader/writer目录下的plugin_job_template.json下的name属性完全一致。处理还会加载前置处理plugin和后置的plugin,博主在源码debug时并未配置这两项的plugin。
public static Configuration parse(final String jobPath) {
//加载我们配置job的json配置文件,我这里是mysql2mysql.json配置文件,配置文件
//可以参考我上一篇文章当中的配置
Configuration configuration = ConfigParser.parseJobConfig(jobPath);
//将我们配置mysql2mysql.json文件的属性和core.json文件的属性合并。
configuration.merge(
//加载{you datax path}/conf/core.json文件
ConfigParser.parseCoreConfig(CoreConstant.DATAX_CONF_PATH),
false);
//根据配置文件读取reader配置
String readerPluginName = configuration.getString(
CoreConstant.DATAX_JOB_CONTENT_READER_NAME);
//根据配置文件读取writer配置
String writerPluginName = configuration.getString(
CoreConstant.DATAX_JOB_CONTENT_WRITER_NAME);
//读取前置处理plugin
String preHandlerName = configuration.getString(
CoreConstant.DATAX_JOB_PREHANDLER_PLUGINNAME);
//读取后置处理plugin
String postHandlerName = configuration.getString(
CoreConstant.DATAX_JOB_POSTHANDLER_PLUGINNAME);
Set<String> pluginList = new HashSet<String>();
pluginList.add(readerPluginName);
pluginList.add(writerPluginName);
if(StringUtils.isNotEmpty(preHandlerName)) {
pluginList.add(preHandlerName);
}
if(StringUtils.isNotEmpty(postHandlerName)) {
pluginList.add(postHandlerName);
}
try {
//加载所有的插件配置文件,我们暂时只有reader和writer插件,即mysqlReader和mysqlWriter,将配置文件合并
configuration.merge(parsePluginConfig(new ArrayList<String>(pluginList)), false);
}catch (Exception e){
//吞掉异常,保持log干净。这里message足够。
LOG.warn(String.format("插件[%s,%s]加载失败,1s后重试... Exception:%s ", readerPluginName, writerPluginName, e.getMessage()));
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
//
}
configuration.merge(parsePluginConfig(new ArrayList<String>(pluginList)), false);
}
return configuration;
}
到此为止我们的前期最关键的一个步骤就完成了,解析所有需要的配置项json,最终我们加载出来的配置文件格式如下:
{
"internal": {
"common": {
"column": {
"dateFormat": "yyyy-MM-dd",
"datetimeFormat": "yyyy-MM-dd HH:mm:ss",
"encoding": "utf-8",
"extraFormats": [
"yyyyMMdd"
],
"timeFormat": "HH:mm:ss",
"timeZone": "GMT+8"
}
},
"core": {
"container": {
"job": {
"id": -1,
"mode": "standalone",
"reportInterval": 10000
},
"taskGroup": {
"channel": 5
},
"trace": {
"enable": "false"
}
},
"dataXServer": {
"address": "http://localhost:7001/api",
"reportDataxLog": false,
"reportPerfLog": false,
"timeout": 10000

最低0.47元/天 解锁文章
3395

被折叠的 条评论
为什么被折叠?



