Spring Boot 任務調度

2.1.12 定時任務

Spring 框架自帶任務調度功能,比如一個輕量級的Quartz,使用簡單、方便,不須要依賴其餘JAR包。java

只須要在項目主程序啓動類上添加@EnableScheduling開啓任務調度功能便可數據庫

@SpringBootApplication
@EnableScheduling
public class LearnApplication {
    public static void main(String[] args) {
        SpringApplication.run(LearnApplication.class, args);
    }
}
2.1.12.1 簡單定時任務
@Component
public class TestTask {

    @Scheduled(cron = "0/10 * * * * *")
    public void testTask1() {
        System.out.println("【任務一】測試定時任務" + LocalDateTime.now());
    }

}

如上述,配置一個簡單的定時任務只須要在調度方法上添加@Shceduled註解便可,就可使用定時任務。markdown

2.1.12.2 異步定時任務
@Component
// 開啓異步支持
@EnableAsync
public class TestTask {

    @Scheduled(cron = "0/10 * * * * *")
    // 方法使用異步執行,每次任務建立一個線程執行任務
    @Async
    public void testTask1() {
        System.out.println("【任務一】測試定時任務" + LocalDateTime.now() + "   " + Thread.currentThread().getName());
        for (int i = 0; i < 20; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("【任務一】休眠" + (i + 1) + "秒測試定時任務" + LocalDateTime.now() + "   " + Thread.currentThread().getName());
        }

    }

}

每每在咱們的項目調度任務中,有的場景是須要在當前任務尚未執行完畢時,就須要執行下一個定時調度任務,在這種狀況下須要使用異步的方式來執行定時任務。框架

@EnableAsync開啓異步支持異步

@Async標記任務使用異步執行(下次任務將在下一個配置時間開始,不等待當前任務執行完畢)ide

2.1.12.3 動態定時任務

當咱們編寫定時任務是,流程大體爲:編碼->配置執行週期->啓動服務。測試

當前咱們配置的執行週期是天天早上8點執行,當咱們有天,需求變動,須要天天晚上8點執行,咱們的操做流程爲:修改執行週期->新版打包->停服->啓動新版服務。整個流程線步驟多,存在不可控因素。編碼

那麼咱們怎麼作到不停服更新咱們的執行週期呢??線程

那麼下面咱們模擬將cron表達式存儲在MySQL。日誌

1)定義cron相關service

// 表達式相關接口
public interface SwitchService {

    /**
     * 獲取最新 cron 表達式
     *
     * @param taskId 任務ID
     * @return 最新 cron表達式
     */
    String getCron(String taskId);

    /**
     * 修改 cron 表達式
     */
    void modify();

}
// 表達式相關接口實現
@Service
public class SwitchServiceImpl implements SwitchService {

    private static String DB_CRON = "";

    @Override
    public String getCron(String taskId) {
        System.out.println("執行數據庫查詢 DB_CRON " + LocalDateTime.now());
        return DB_CRON;
    }

    @Override
    public void modify() {
        DB_CRON = "0/20 * * * * *";
        System.out.println("修改數據庫中 DB_CRON " + LocalDateTime.now());
    }
}

此處模擬修改以及查詢

2)建立具體任務執行

@Component
public class DynamicCronTask implements SchedulingConfigurer {
    // 模擬當前任務ID
    private String TASK_ID = "5001";

    @Autowired
    private SwitchService switchService;

    private String SpringDynamicCronTask() {
        // 默認爲 每5秒執行
        String cron = "0/5 * * * * ?";
        //從數據庫得到配置的corn表達式
        String dbCron = switchService.getCron(TASK_ID);
        // 當查詢爲空時,使用默認的表達式
        if (StringUtils.isNotBlank(dbCron)) {
            return dbCron;
        }
        return cron;
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.addTriggerTask(new Runnable() {
            @Override
            public void run() {
                // 任務邏輯
                System.out.println("執行任務邏輯...." + LocalDateTime.now());
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                String s = SpringDynamicCronTask();
                // 任務觸發,可修改任務的執行週期
                CronTrigger trigger = new CronTrigger(s);
                Date nextExec = trigger.nextExecutionTime(triggerContext);
                return nextExec;
            }
        });
    }

}

3)啓動服務

查看執行日誌

執行數據庫查詢 DB_CRON 2020-06-09T10:33:30.001
執行任務邏輯....2020-06-09T10:33:35.002
執行數據庫查詢 DB_CRON 2020-06-09T10:33:35.002
執行任務邏輯....2020-06-09T10:33:40.001
執行數據庫查詢 DB_CRON 2020-06-09T10:33:40.001

修改數據庫中 DB_CRON 2020-06-09T10:33:42.085

執行任務邏輯....2020-06-09T10:33:45
執行數據庫查詢 DB_CRON 2020-06-09T10:33:45

執行任務邏輯....2020-06-09T10:34:00.001
執行數據庫查詢 DB_CRON 2020-06-09T10:34:00.001
執行任務邏輯....2020-06-09T10:34:20.002
執行數據庫查詢 DB_CRON 2020-06-09T10:34:20.002

經過日誌能夠看出,在應用啓動時,會首先從數據庫中查詢配置的執行週期,而後執行定時任務,執行完畢後會再次查詢執行週期,下一個執行時間結束後就會按照修改的執行時間執行。

生效時間爲下一個執行時間結束後,作不到當即生效!!!

相關文章
相關標籤/搜索