博客中若有侵权或者错误的地方,请及时告知,感谢。
1.背景
在项目中会遇到执行定时任务场景,例如定时轮训关闭未支付订单,定时同步数据等。springtask就可以满足这些场景需求。但是若对springtask理解不深,可能会达不到我们期待的效果。例如springtask默认是单线程串行执行,这里对springtask添加线程池,以及异步执行进行探索。
2.实践
简单3个定时任务如下
@EnableScheduling
@Component
@Slf4j
public class ReloadTask {
@Scheduled(cron = "0/1 * * * * ?")
public void task1() {
String traceId = IdUtil.simpleUUID();
log.info("begin task1 traceId:{}", traceId);
long beginTime = System.currentTimeMillis();
try {
Thread.sleep(5000);
} catch (Exception e) {
log.error("task1 traceId:{}", traceId, e);
}
log.info("end task1 cost:{}, traceId:{}", System.currentTimeMillis() - beginTime, traceId);
}
@Scheduled(cron = "0/2 * * * * ?")
public void task2() {
String traceId = IdUtil.simpleUUID();
log.info("begin task2 traceId:{}", traceId);
long beginTime = System.currentTimeMillis();
try {
Thread.sleep(5000);
} catch (Exception e) {
log.error("task2 traceId:{}", traceId, e);
}
log.info("end task2 cost:{}, traceId:{}", System.currentTimeMillis() - beginTime, traceId);
}
@Scheduled(cron = "0/3 * * * * ?")
public void task3() {
log.info("exec task3");
}
}
2.1 默认情况
通过执行日志可以发现,使用单个线程,串行执行,执行task1之后再执行task2再task3
2024-06-16 10:58:24.011 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : begin task1 traceId:73c94e2dc5d34be58fe6fabc567efec8
2024-06-16 10:58:29.015 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : end task1 cost:5003, traceId:73c94e2dc5d34be58fe6fabc567efec8
2024-06-16 10:58:29.016 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : begin task2 traceId:029cf87bc45d4a6e90081aee5437aadc
2024-06-16 10:58:34.020 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : end task2 cost:5004, traceId:029cf87bc45d4a6e90081aee5437aadc
2024-06-16 10:58:34.020 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : exec task3
2024-06-16 10:58:34.020 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : begin task1 traceId:68f4d321445e4b62a6c163a4ce2aaa91
2024-06-16 10:58:39.023 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : end task1 cost:5002, traceId:68f4d321445e4b62a6c163a4ce2aaa91
2024-06-16 10:58:39.024 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : begin task2 traceId:7cd230202e35438d979b217907adaf94
2024-06-16 10:58:44.026 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : end task2 cost:5002, traceId:7cd230202e35438d979b217907adaf94
2024-06-16 10:58:44.026 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : exec task3
2024-06-16 10:58:44.027 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : begin task1 traceId:b9b7d7fba9414264b3e62bfbf4fcf7d3
2024-06-16 10:58:49.029 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : end task1 cost:5002, traceId:b9b7d7fba9414264b3e62bfbf4fcf7d3
2024-06-16 10:58:49.030 INFO 3396 — [ scheduling-1] com.test.task.ReloadTask : exec task3
2.2 使用线程池执行定时任务
通过执行日志可以发现,使用多个线程,单个任务串行执行,多个任务并行执行
spring.task.scheduling.pool.size=12
spring.task.scheduling.thread-name-prefix=schedulertask-
2024-06-16 10:41:51.005 INFO 3119 — [schedulertask-1] com.test.task.ReloadTask : exec task3
2024-06-16 10:41:51.015 INFO 3119 — [schedulertask-2] com.test.task.ReloadTask : begin task1 traceId:4e20d58512b047e9a644c8dd3b637bf1
2024-06-16 10:41:52.003 INFO 3119 — [schedulertask-3] com.test.task.ReloadTask : begin task2 traceId:05d016976cb34ca0a5d538f4499be742
2024-06-16 10:41:54.001 INFO 3119 — [schedulertask-1] com.test.task.ReloadTask : exec task3
2024-06-16 10:41:56.017 INFO 3119 — [schedulertask-2] com.test.task.ReloadTask : end task1 cost:5001, traceId:4e20d58512b047e9a644c8dd3b637bf1
2024-06-16 10:41:57.005 INFO 3119 — [schedulertask-1] com.test.task.ReloadTask : exec task3
2024-06-16 10:41:57.005 INFO 3119 — [schedulertask-4] com.test.task.ReloadTask : begin task1 traceId:cef8ba7899a343c38bbf51fbeabb6699
2024-06-16 10:41:57.005 INFO 3119 — [schedulertask-3] com.test.task.ReloadTask : end task2 cost:5002, traceId:05d016976cb34ca0a5d538f4499be742
2024-06-16 10:41:58.001 INFO 3119 — [schedulertask-2] com.test.task.ReloadTask : begin task2 traceId:17f530d4725a454e904cf2b4415d2f8b
2024-06-16 10:42:00.002 INFO 3119 — [schedulertask-6] com.test.task.ReloadTask : exec task3
2024-06-16 10:42:02.009 INFO 3119 — [schedulertask-4] com.test.task.ReloadTask : end task1 cost:5004, traceId:cef8ba7899a343c38bbf51fbeabb6699
2024-06-16 10:42:03.000 INFO 3119 — [schedulertask-1] com.test.task.ReloadTask : exec task3
2024-06-16 10:42:03.000 INFO 3119 — [schedulertask-3] com.test.task.ReloadTask : begin task1 traceId:3b3578ade6334604bfb2e40636d97c49
2024-06-16 10:42:03.005 INFO 3119 — [schedulertask-2] com.test.task.ReloadTask : end task2 cost:5004, traceId:17f530d4725a454e904cf2b4415d2f8b
2024-06-16 10:42:04.005 INFO 3119 — [schedulertask-2] com.test.task.ReloadTask : begin task2 traceId:41d30a767d8c4071a7bbf13a0eed493a
2024-06-16 10:42:06.005 INFO 3119 — [schedulertask-1] com.test.task.ReloadTask : exec task3
2024-06-16 10:42:08.001 INFO 3119 — [schedulertask-3] com.test.task.ReloadTask : end task1 cost:5001, traceId:3b3578ade6334604bfb2e40636d97c49
2024-06-16 10:42:09.000 INFO 3119 — [schedulertask-3] com.test.task.ReloadTask : begin task1 traceId:ea580f0d1c93490286778c51691e6839
2024-06-16 10:42:09.000 INFO 3119 — [schedulertask-4] com.test.task.ReloadTask : exec task3
2024-06-16 10:42:09.006 INFO 3119 — [schedulertask-2] com.test.task.ReloadTask : end task2 cost:5000, traceId:41d30a767d8c4071a7bbf13a0eed493a
2024-06-16 10:42:10.005 INFO 3119 — [schedulertask-2] com.test.task.ReloadTask : begin task2 traceId:7dd14efdd75a4f15b5f0547a0a6e03d7
2024-06-16 10:42:12.002 INFO 3119 — [schedulertask-4] com.test.task.ReloadTask : exec task3
2.3 使用@async并且配置异步线程池执行定时任务
通过执行日志可以发现,使用多个线程,单个任务异步执行不会相互等待,多个任务并行执行
2024-06-16 10:48:42.023 INFO 3236 — [test-asynctask-3] com.test.task.ReloadTask : exec task3
2024-06-16 10:48:42.029 INFO 3236 — [test-asynctask-2] com.test.task.ReloadTask : begin task1 traceId:c059fe655ba04f09bdee21ad3106346b
2024-06-16 10:48:42.029 INFO 3236 — [test-asynctask-1] com.test.task.ReloadTask : begin task2 traceId:741b3a8c1e824984987602dcff1f9440
2024-06-16 10:48:43.005 INFO 3236 — [test-asynctask-4] com.test.task.ReloadTask : begin task1 traceId:6fd6c132c4844e5c8df2a7a678472b81
2024-06-16 10:48:44.004 INFO 3236 — [test-asynctask-5] com.test.task.ReloadTask : begin task2 traceId:2533f51f90964001affc8b9676ef054a
2024-06-16 10:48:44.004 INFO 3236 — [test-asynctask-6] com.test.task.ReloadTask : begin task1 traceId:8f2360ff84b24cd1a0d4a5c53643c178
2024-06-16 10:48:45.002 INFO 3236 — [test-asynctask-7] com.test.task.ReloadTask : begin task1 traceId:bc00822ae082452a8ae6367fed90a695
2024-06-16 10:48:45.002 INFO 3236 — [test-asynctask-8] com.test.task.ReloadTask : exec task3
2024-06-16 10:48:46.003 INFO 3236 — [test-asynctask-10] com.test.task.ReloadTask : begin task1 traceId:fce45e092bcc4936acdb641e81e41c63
2024-06-16 10:48:46.004 INFO 3236 — [test-asynctask-9] com.test.task.ReloadTask : begin task2 traceId:ec08f5fc744142c9909e06cb708a7d32
2024-06-16 10:48:47.004 INFO 3236 — [test-asynctask-11] com.test.task.ReloadTask : begin task1 traceId:8c209596ad3143328ef1a4a75480c5f5
2024-06-16 10:48:47.032 INFO 3236 — [test-asynctask-2] com.test.task.ReloadTask : end task1 cost:5002, traceId:c059fe655ba04f09bdee21ad3106346b
2024-06-16 10:48:47.032 INFO 3236 — [test-asynctask-1] com.test.task.ReloadTask : end task2 cost:5002, traceId:741b3a8c1e824984987602dcff1f9440
2024-06-16 10:48:48.001 INFO 3236 — [test-asynctask-12] com.test.task.ReloadTask : begin task1 traceId:4e21a2c55d5c4b14b19a4b0417edcc47
2024-06-16 10:48:48.001 INFO 3236 — [test-asynctask-14] com.test.task.ReloadTask : begin task2 traceId:8f7ae6d938744c83a958de504e213b47
2024-06-16 10:48:48.002 INFO 3236 — [test-asynctask-13] com.test.task.ReloadTask : exec task3