Java Quartz 和 Python 结合使用达到强大的应用范围
前言 #
之前的公司技术栈C#居多,再后来公司需要一套定时任务系统来处理各系统的调度来弥补WMS和各系统之间调度的缺陷,因此选用了一个开源的C#开发的定时任务系统。
而我被分配到一个数据清洗程序的开发,需求是从大量数据的MongoDB将数据清洗至另一个SqlServer,要具备一定的实时性,因为MongoDB里面的产品测试数据是一直在增长的。
而我想到了定时任务和Python,然后就想到,用Java开发一个Web定是任务管理平台,而执行的是Python脚本。
这能解决什么问题呢?
1.脚本可以动态添加,动态修改,无需修改任何Java代码,因为Python是脚本语言,不存在编译过程,改了就生效,就能运行。
2.可以在Python环境的服务器通过PIP安装很多第三方库,能做非常多的事情,比如定时爬虫,定时API调用,定时数据清洗等等。
事实证明确实方便,开发完成后,之前的调度系统就废弃了,转而使用我的这套定时任务系统。
设计 #
使用相关技术:Java Quartz,MySql数据库,Python脚本。
数据库表:
脚本表
还有一个用于记录数据清洗指针的表:
一共就这么几张表。
开发逻辑是,先将脚本写好,然后上传到网站,创建定时任务时指定脚本进行关联,保证在JOB执行时能拿到脚本相关数据就行:
@SneakyThrows
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
/ System.out.println(jobExecutionContext.getJobDetail().getJobDataMap().get("test"));
// System.out.println(jobExecutionContext.getJobDetail().getJobDataMap().get("test"));
String key = jobExecutionContext.getJobDetail().getKey().getName();
// jobSocketServer.sendInfo(jobExecutionContext.getTrigger().getJobKey().getName(), "SayHelloJob.execute , hello world ! ");
if (jobExecutionContext.getJobDetail().getJobDataMap().containsKey("script")) {
ScriptPath scriptPath = (ScriptPath) jobExecutionContext.getMergedJobDataMap().get("script");
String execOption = (String) jobExecutionContext.getMergedJobDataMap().get("execOption");
// jobExecutionContext.getScheduler().getTriggersOfJob(jobExecutionContext.getJobDetail().getKey()).get(0).getJobDataMap();
ExecRecord execRecord = new ExecRecord();
execRecord.setStartTime(new Date());
execRecord.setScript(scriptPath.getFileName());
execRecord.setJob(key);
execRecordRepository.save(execRecord);
StringBuilder cmdBuild = new StringBuilder("python -u " + scriptPath.getFileName());
if (!Strings.isEmpty(execOption)){
cmdBuild.append(" ");
cmdBuild.append(execOption);
}
CMDUtil.runCmd(jobSocketServer, cmdPath, cmdBuild.toString(), key);
log.info(String.format("开始执行: %s", cmdBuild.toString()));
jobSocketServer.sendInfo(key, "<p style='color=red'>结束.</p>");
} else {
jobSocketServer.sendInfo(key, "<p style='color=red'>结束.</p>");
}
}