SpringBoot Scheduled 常見用法

外部統一管理可用 xxl-job ,將各定時任務集中管理,靈活改變執行頻率,支持某一個定時器集羣處理,避免多服務啓動時,每個服務都執行(重複執行)

比如我的API服務裏有一個定時任務,將API做成集羣時,變成了 API1、API2、API3 ,這時候每個API都有定時任務。但我只能讓一個執行,不能也沒必要三個API都執行。就只能將定時任務獨立成一個 應用發佈,或者發佈時只開啓一個,另外兩個不開啓。

有了XXL-JOB,1、2、3只會輪訓執行一次。

Spring 自帶的 Schedule 用法 

@Component
@EnableScheduling
public class CronTask1 {
    Logger taskLogger = LoggerFactory.getLogger(this.getClass());

    /**
     * @Scheduled除過cron還有三種方式:fixedRate,fixedDelay,initialDelay
     * cron:表達式可以定製化執行任務,但是執行的方式是與fixedDelay相近的,也是會按照上一次方法結束時間開始算起。
     * fixedRate:控制方法執行的間隔時間,是以上一次方法執行完開始算起,如上一次方法執行阻塞住了,那麼直到上一次執行完,並間隔給定的時間後,執行下一次。
     * fixedDelay:是按照一定的速率執行,是從上一次方法執行開始的時間算起,如果上一次方法阻塞住了,下一次也是不會執行,但是在阻塞這段時間內累計應該執行的次數,當不再阻塞時,一下子把這些全部執行掉,而後再按照固定速率繼續執行。
     * initialDelay:initialDelay = 10000 表示在容器啓動後,延遲10秒後再執行一次定時器。
     */
    @Scheduled(cron = "*/6 * * * * ?")
    public void crontabTask() {
        taskLogger.info("這是基於註解的方式的定時任務" + new Date());
    }

    //內部控制,可加條件判斷是否要啓用
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.addTriggerTask(() -> process(),
                triggerContext -> {
                    //每隔1分鐘執行一次
                    String cron = "10,20 * * * * ?";
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                });
    }
    private void process() {
        String info = "這是基於接口的定時任務";
        System.out.println(info);
        taskLogger.info(info);
    }

}

多線程定時任務

@Component
@EnableScheduling
@EnableAsync
public class CronTask3 {
    Logger taskLogger = LoggerFactory.getLogger("crontabTask_3");

    @Async
    @Scheduled(fixedDelay = 10000)  //間隔10秒
    public void first() throws InterruptedException {
        System.out.println("第一個定時任務開始 : " + LocalDateTime.now().toLocalTime() + "\r\n線程 : " + Thread.currentThread().getName());
        taskLogger.info("第一個基於註解設定多線程定時任務");
        Thread.sleep(1000 * 10);
    }

    @Async
    @Scheduled(fixedDelay = 20000)
    public void second() {
        System.out.println("第二個定時任務開始 : " + LocalDateTime.now().toLocalTime() + "\r\n線程 : " + Thread.currentThread().getName());
        taskLogger.info("第二個基於註解設定多線程定時任務");

    }
}

 

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