apache / shardingsphere-elasticjob

Distributed scheduled job
Apache License 2.0
8.15k stars 3.29k forks source link

动态添加定时任务,重新系统后还未执行的定时任务启动后不再执行,通过api 也恢复不了 #485

Closed liangpeichang closed 6 years ago

liangpeichang commented 6 years ago

Please answer these questions before submitting your issue. Thanks! 开源不易,我们希望将精力放在完成新功能和解决有价值的问题上,为了让大家的配合更具有效率,请填写以下列出的全部问题

Which version of Elastic-Job do you using?(您使用的Elastic-Job版本为?)

2.1.0

Expected behavior (您预期的结果是)

希望重启服务后,周期性定时任务还可以自动执行下去

Actual behavior (实际运行的结果是)

1、重启系统服务后,还未执行的定时任务,到了时间后不再执行

2、通过api 进行恢复、关闭、立即运行定时任务,定时任务没有任何效果

Steps to reproduce the behavior (可重现问题的操作步骤)

1、(1)启动系统后,通过页面链接点击添加定时任务,会通过后台代码动态添加一个定时任务, 设置0/20 ? ,每20秒执行一次。 1、(2)然后重新启动系统后,以前创建的定时任务就不会再执行,以前用的quartz 框架重新启动系统后就可以继续自动执行,而此elastic-job-lite 就不再执行了 2、通过api trigger,enable,shutdown 操作job,原来job 的状态是 CRASHED ,操作后仍旧是CRASHED

Please provide the reproduce example codes (such as github link),otherwise we will label the issue as Invalid and close it.(为了节省复现问题的时间,请务必提供可重现的代码,否则我们会将issue直接标记为invalid并关闭)

xml配置:

java 代码,点击页面链接调用addJob方法动态添加定时任务: @RestController @RequestMapping("/job") public class DynamicJob { @Resource private CoordinatorRegistryCenter regCenter; @Resource private JobEventRdbConfiguration jobEventRdbConfiguration; private static final String ACTIVITY_JOB_CLASS = ActivityJob.class.getCanonicalName(); @Autowired private JobSettingsAPI jobSettingsAPI; @Autowired private JobOperateAPI jobOperateAPI; @Autowired private JobStatisticsAPI jobStatisticsAPI; /**

  • 本机IP */ private static final Optional serverIp = Optional.of(IpUtils.getIp()); /* @description 测试周期执行定时任务 @date 2018年2月12日 @param jobName @return / @RequestMapping("/addJob") public String addJob(String jobName){ JobParametersBean jobParametersBean = new JobParametersBean(); jobParametersBean.setJobName(UUID.randomUUID().toString()+jobName); jobParametersBean.setJobCorn("0/20 ?");//仅仅写两个参数测试 //注意job name 不能重复 JobCoreConfiguration coreConfig = JobCoreConfiguration .newBuilder(jobParametersBean.getJobName(), jobParametersBean.getJobCorn(), 1)//每20秒执行一次定时任务,任务总片数为1 .shardingItemParameters("0=a") .jobParameter(JSONUtils.toJSONString(jobParametersBean)) .build(); SimpleJobConfiguration jobConfig = new SimpleJobConfiguration(coreConfig, ACTIVITY_JOB_CLASS); LiteJobConfiguration liteJobConfig = LiteJobConfiguration.newBuilder(jobConfig ).overwrite(true).build(); //job 监听器 ,在job 任务执行前先执行 new JobScheduler(regCenter, liteJobConfig, jobEventRdbConfiguration,new ActivityJobListener()).init(); return "ok"; } //获取所有未执行的定时任务 @RequestMapping("/getAllNoExecuteJob") public void getAllNoExecuteJob(){ Collection jobBrief = jobStatisticsAPI.getAllJobsBriefInfo(); System.out.println(jobBrief.size()+"size"); for (Iterator iterator = jobBrief.iterator(); iterator.hasNext();) { JobBriefInfo jobBriefInfo = (JobBriefInfo) iterator.next(); System.out.println(jobBriefInfo.getStatus()+"status...................."+jobBriefInfo.getJobName()); } } //恢复任务 @RequestMapping("/enable") public void enable(){ Collection jobBrief = jobStatisticsAPI.getAllJobsBriefInfo(); for (Iterator iterator = jobBrief.iterator(); iterator.hasNext();) { JobBriefInfo jobBriefInfo = (JobBriefInfo) iterator.next(); //定时任务已经失效,恢复 if(JobBriefInfo.JobStatus.CRASHED.equals(jobBriefInfo.getStatus())){ jobOperateAPI.enable(Optional.of(jobBriefInfo.getJobName()),serverIp); } } } //立刻执行 @RequestMapping("/trigger") public void trigger(){ Collection jobBrief = jobStatisticsAPI.getAllJobsBriefInfo(); for (Iterator iterator = jobBrief.iterator(); iterator.hasNext();) { JobBriefInfo jobBriefInfo = (JobBriefInfo) iterator.next(); if(JobBriefInfo.JobStatus.CRASHED.equals(jobBriefInfo.getStatus())){ jobOperateAPI.trigger(Optional.of(jobBriefInfo.getJobName()),serverIp); } } } //作业关闭 @RequestMapping("/shutdown") public void shutdown(){ Collection jobBrief = jobStatisticsAPI.getAllJobsBriefInfo(); for (Iterator iterator = jobBrief.iterator(); iterator.hasNext();) { JobBriefInfo jobBriefInfo = (JobBriefInfo) iterator.next(); //定时任务已经失效,关闭 if(JobBriefInfo.JobStatus.CRASHED.equals(jobBriefInfo.getStatus())){ jobOperateAPI.shutdown(Optional.of(jobBriefInfo.getJobName()),serverIp); } } } //作业更新后启用 @RequestMapping("/update") public void update(){ Collection jobBrief = jobStatisticsAPI.getAllJobsBriefInfo(); for (Iterator iterator = jobBrief.iterator(); iterator.hasNext();) { JobBriefInfo jobBriefInfo = (JobBriefInfo) iterator.next(); if(JobBriefInfo.JobStatus.CRASHED.equals(jobBriefInfo.getStatus())){ JobSettings jobSettings = jobSettingsAPI.getJobSettings(jobBriefInfo.getJobName()); jobSettingsAPI.updateJobSettings(jobSettings); jobOperateAPI.enable(Optional.of(jobBriefInfo.getJobName()),serverIp); } } } } //定时任务真正执行类: public class ActivityJob implements SimpleJob {

    @Override public void execute(ShardingContext shardingContext) { System.out.println(shardingContext+"简单定时任务执行了。。。。。。。。。。。。。。。。。。。"); }

} Code should based on https://github.com/elasticjob/elastic-job-example (代码请基于 https://github.com/elasticjob/elastic-job-example

haocao commented 6 years ago

请先阅读文档http://elasticjob.io/docs/elastic-job-lite/01-start/faq/中关于动态添加作业部分的描述。

  1. 是否支持动态添加作业? 回答:

动态添加作业这个概念每个人理解不尽相同。

elastic-job-lite为jar包,由开发或运维人员负责启动。启动时自动向注册中心注册作业信息并进行分布式协调,因此并不需要手工在注册中心填写作业信息。 但注册中心与作业部署机无从属关系,注册中心并不能控制将单点的作业分发至其他作业机,也无法将远程服务器未启动的作业启动。elastic-job-lite并不会包含ssh免密管理等功能。

elastic-job-cloud为mesos框架,由mesos负责作业启动和分发。 但需要将作业打包上传,并调用elastic-job-cloud提供的REST API写入注册中心。 打包上传属于部署系统的范畴elastic-job-cloud并未涉及。

综上所述,elastic-job已做了基本动态添加功能,但无法做到真正意义的完全自动化添加。