springboot整合quarzt實現動態定時任務

實現定時任務的幾種方式:

1.使用linux的crontab

優勢:
	1.使用方式很簡單,只要在crontab中寫好
	2.隨時能夠修改,不須要重啓服務器
缺點:
	1.分佈式的系統中很差使用,只能一臺臺機器去修改
	2.分是最小的時間單位,秒級的不能使用
複製代碼

2.使用spring自帶的ScheduledExecutor

優勢:
	cronExpression比crontab的更強大一些支持到秒,性能更好
缺點:
	修改了cronExpression的重啓服務器,不然不生效
複製代碼

3. 使用JDK自帶的Timer

優勢: 
    輕量級,執行速度快
缺點:
    分佈式系統很差使用.並且不能指定時間執行,只能按某個頻次來執行
複製代碼

4. 使用quartz

優勢:
    1.可適用於分佈式系統,quartz可支持集羣模式
    2.修改了定時任務無須重啓服務器(這只是我我的想到的一些優缺點,網友有其餘見解能夠留言說下)
複製代碼

整合步驟:

咱們如今知道了quartz有這麼優秀,該怎麼整合到項目中呢?筆者接下來將實現一個經過http接口調用來觸發動態定時任務的一個小功能. 筆者使用的環境: jdk:1.8.0_162; springboot:1.5.10.RELEASE 1.引入須要的jar包,在pom文件中加入quartz的jar包和spring支持quartz的jarhtml

<dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
複製代碼

2.配置調度器的bean,這裏spring實現了三個工廠類,SchedulerFactoryBean,CronTriggerBean,JobDetailBean,使用註解的方式將這三個類交給spring管理.通常看網上的資料都是這三個類,都交給spring管理,能夠參考這篇文章這篇文章。     而我這裏定時任務的觸發是要經過接口的方式來觸發,因此只用實現如下SchedulerFactoryBean的調度器便可。若是讀者不是很明白這幾個類是幹嗎的,能夠看下quartz使用的文章。 我這裏簡單說下: scheduler:任務的調度器,job:具體的任務類,trigger:觸發器,任務何時執行是由它決定的。就是說時間人物作什麼,scheduler就是主語的人物,trigger是時間,job是作什麼事。java

@Configuration
public class SchedulerConfig {

    /** * attention: * Details:定義quartz調度工廠 */
    @Bean(name = "scheduler")
    public SchedulerFactoryBean schedulerFactory() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        // 用於quartz集羣,QuartzScheduler 啓動時更新己存在的Job
        bean.setOverwriteExistingJobs(true);
        // 延時啓動,應用啓動1秒後
        bean.setStartupDelay(1);
        return bean;
    }
}
複製代碼

3.具體任務類job,必須實現quartz的job類,這個也能夠去實現spring的QuartJobBean(spring對job類的實現)是同樣的,或者還有一種方式就是MethodInvokingJobDetailFactoryBean,這個類裏面能夠設置什麼類的什麼方法來執行這個任務,會更靈活一些:linux

@Slf4j
public class ScheduleTaskJob implements Job {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        log.info("任務執行了......");
    }
}
複製代碼

4.http的接口來觸發該調度程序:git

@Slf4j
@RestController
public class Controller {

    @Resource(name = "scheduler")
    private Scheduler scheduler;

    @PostMapping(value = "/api/executeTask")
    public String executeTask(TaskVO taskVO) {
        // job類
        JobDetail jobDetail = JobBuilder.newJob(ScheduleTaskJob.class)
               .withIdentity(taskVO.getJobName(), taskVO.getJobGroupName())
                .build();
        // 觸發器類
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(taskVO.getTriggerName(), taskVO.getTriggerGroupName())
                .startNow()
                .withSchedule(cronSchedule(taskVO.getCronExpression()))
                .build();
        try {
            // 執行任務
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            log.error("任務執行異常", e);
        }
        return "success";
    }
}
複製代碼

5.http接口傳入的值對象,其實就是用來指定job和triger的name和groupName,name相同的話會失敗,必須是惟一的, 6.執行程序看看效果: 我傳入的參數: jobName:job1 jobGroupName:jobGroup1 triggerName:trigger1 triggerGroupName:triggerGroup1 cronExpression:0/1 * * * * ?github

jobName:job2 jobGroupName:jobGroup1 triggerName:trigger2 triggerGroupName:triggerGroup1 cronExpression:0/1 * * * * ? spring

在這裏插入圖片描述

圖中紅色方框上部是隻有一個定時任務,每一秒執行一次,下部由於又加入了一個新的任務因此回答引出兩個任務的執行結果。api

遇到的坑:

1.java.lang.NoSuchMethodError: org.springframework.boot.SpringApplication.run(Ljava/lang/Object;[Ljava/lang/String;)Lorg/springframework/context/ConfigurableApplicationContext; 解決方式:這個是由於springboot2不兼容的問題,因此使用springboot1.5是不會出現這個錯誤的。springboot

2.Caused by: java.lang.ClassNotFoundException: org.springframework.transaction.PlatformTransactionManager at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_162] at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_162] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) ~[na:1.8.0_162] at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_162] 39 common frames omitted 啓動的時候若是報這個錯的話,要引入一個spring-tx事物的包bash

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
 </dependency>
複製代碼

源碼地址:github源碼地址,朋友們以爲寫得還行的幫忙star個,follower下,23333,感謝~

參考資料:

[1]blog.csdn.net/liuchuanhon… [2]www.w3cschool.cn/quartz_doc/… [3]www.ibm.com/developerwo… [4]www.quartz-scheduler.org/服務器

相關文章
相關標籤/搜索