外部統一管理可用 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("第二個基於註解設定多線程定時任務"); } }