分布式服务下Quartz任务框架配置

   公司在使用Spring Cloud微服务架构,同时都使用Quartz任务框架进行任务调度,具体的结构如下所示:


  配置具体见我的另一博文 http://blog.csdn.net/u011687186/article/details/72461102

  但是存在这样一个问题,各个服务互相不相关,假如一个发起Job任务的服务挂掉以后,在到达执行任务的时间时,其它服务会执行这个任务,由于其它服务中没有这个Job类,就会报错,并且把这个job的状态变为ERROR,这样可不行。

  后来我的解决思路是,把任务单独起一个JOB服务器出来,其它的服务需要执行任务的时候,向这个JOB服务器发送。


但是这样又有一个问题,就是当在任务服务器将要执行任务的时候,需要完成任务的类在其它的服务器上,这个这么办,后来我想到了SpringCloud Ribbon,我把服务暴露了,在保存job的时候,把相应的(服务器1)的地址也保存上,然后在执行类的时候向(服务器1)使用Ribbon就行通信调用,

/**
 * Created by mengxiangrui on 2017/6/15.
 */
public class QuartzJob implements Job {
    @Resource
    private RestTemplate restTemplate;
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //获取JobDataMap
        JobDataMap dataMap = jobExecutionContext.getJobDetail().
                getJobDataMap();
        String url = (String) dataMap.get(QuartzComn.url);
        JSONObject jsonObject = new JSONObject();
        for (Map.Entry<String,Object> entry : dataMap.entrySet()) {
            if(!QuartzComn.url.equals(entry.getKey())){
                jsonObject.put(entry.getKey(),entry.getValue());
            }
        }
        restTemplate.getForEntity(url,Boolean.class,jsonObject);
    }
}
但是这样做,把所有的任务都放在了一台服务器上压力比较大,并且各个服务间耦合度较大,偏离的服务化的思想,还是想用原方法配置的方式解决,后来经过研究发现Quartz可以区分使用设置 SchedulerFactoryBean的名称,

我们把每个服务的SchedulerFactoryBean按照服务名称命名,就解决了服务宕机任务报错问题。

        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setSchedulerName(NoticeConstant.quartzScheduleName);
        // this allows to update triggers in DB when updating settings in config file:
        factory.setOverwriteExistingJobs(true);
        factory.setJobFactory(jobFactory);
        factory.setDataSource(dataSource);
        factory.setQuartzProperties(quartzProperties());
        return factory;
设置SchedulerFactoryBean的作用。
SCHED_NAME VARCHAR(120) NOT NULL COMMENT 'Scheduler名称,同一集群下的Scheduler实例名称相同,Instance_Id不同'

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章