CJ.Blog


Java Quartz 和 Python 结合使用达到强大的应用范围

前言 #

之前的公司技术栈C#居多,再后来公司需要一套定时任务系统来处理各系统的调度来弥补WMS和各系统之间调度的缺陷,因此选用了一个开源的C#开发的定时任务系统。

而我被分配到一个数据清洗程序的开发,需求是从大量数据的MongoDB将数据清洗至另一个SqlServer,要具备一定的实时性,因为MongoDB里面的产品测试数据是一直在增长的。

而我想到了定时任务和Python,然后就想到,用Java开发一个Web定是任务管理平台,而执行的是Python脚本。

这能解决什么问题呢?

1.脚本可以动态添加,动态修改,无需修改任何Java代码,因为Python是脚本语言,不存在编译过程,改了就生效,就能运行。

2.可以在Python环境的服务器通过PIP安装很多第三方库,能做非常多的事情,比如定时爬虫,定时API调用,定时数据清洗等等。

事实证明确实方便,开发完成后,之前的调度系统就废弃了,转而使用我的这套定时任务系统。

设计 #

使用相关技术:Java Quartz,MySql数据库,Python脚本。

数据库表

脚本表

img

img

还有一个用于记录数据清洗指针的表:

img

一共就这么几张表。

开发逻辑是,先将脚本写好,然后上传到网站,创建定时任务时指定脚本进行关联,保证在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>");
        }


    }