最近發現個生產問題,定時器任務某些任務沒有及時執行。經過研究排查發現spring 定時器任務scheduled-tasks默認配置是單線程串行執行的,這就造成了若某個任務執行時間過長,其他任務一直在排隊,業務邏輯沒有及時處理的問題。
如下是scheduled定義了3個任務。
<task:scheduled-tasks > <task:scheduled ref="myTask1" method="run" cron="0 0/59 10-23 * * ?"/> <task:scheduled ref="myTask2" method="run" cron="0/10 * * * * ?"/> <task:scheduled ref="myTask3" method="run" cron="0/10 * * * * ?"/> </task:scheduled-tasks>
查看該任務17點的執行日志(task名字已修改)
zgrep -e '2016-10-28 17:' channel-task.log.2016-10-28.log.gz | grep -e 'MyTask2'
2016-10-28 17:14:25,002 INFO [pool-8-thread-1 - ] task.AbstractTask - [TASK] start task >> .MyTask2@186d315
2016-10-28 17:14:35,980 INFO [pool-8-thread-1 - ] task.AbstractTask - [TASK] complete task MyTask2@186d315
2016-10-28 17:14:40,002 INFO [pool-8-thread-1 - ] task.AbstractTask - [TASK] start task >> .MyTask2@186d315
2016-10-28 17:14:50,681 INFO [pool-8-thread-1 - ] task.AbstractTask - [TASK] complete task .MyTask2@186d315
2016-10-28 17:14:55,003 INFO [pool-8-thread-1 - ] task.AbstractTask - [TASK] start task >> .MyTask2@186d315
2016-10-28 17:15:05,613 INFO [pool-8-thread-1 - ] task.AbstractTask - [TASK] complete task MyTask2@186d315
2016-10-28 17:20:35,246 INFO [pool-8-thread-1 - ] task.AbstractTask - [TASK] start task >> .MyTask2@186d315
2016-10-28 17:20:46,051 INFO [pool-8-thread-1 - ] task.AbstractTask - [TASK] complete task .MyTask2@186d315
2016-10-28 17:20:50,003 INFO [pool-8-thread-1 - ] task.AbstractTask - [TASK] start task >> .MyTask2@186d315
2016-10-28 17:21:00,974 INFO [pool-8-thread-1 - ] task.AbstractTask - [TASK] complete task MyTask2@186d315
MyTask2每10秒鍾執行一次,但是在17:15:05 到17:20:35之間,5分鍾內定時任務沒有執行
執行命令 zgrep -e '2016-10-28 17:1' task.log.2016-10-28.log.gz (當天17點10幾分發生的日志)
然后在查詢日志發現,這5分鍾之內有大量的日志在執行
2016-10-28 17:17:20,202 INFO [pool-8-thread-1 - ] task.MyTask3 - compare query order[ 211621610280893418 ]
2016-10-28 17:17:20,477 INFO [pool-8-thread-1 - ] task.MyTask3 - compare query order[ 211621610280893401 ]
2016-10-28 17:17:20,731 INFO [pool-8-thread-1 - ] task.MyTask3 - compare query order[ 211621610280893402 ]
.........中間省略n條日志
2016-10-28 17:19:59,752 INFO [pool-8-thread-1 - ] task.MyTask3 - compare query order[ 211621610280894049 ]
通過過以上日志可以看出,該線程[pool-8-thread-1 - ] 一直在處理MyTask3任務,此時斷定 task:scheduled 配置默認是單線程串行的,
網上查找資料發現如下配置可以解決問題
<task:scheduler id="scheduler" pool-size="3" /> <task:scheduled-tasks scheduler="scheduler" > <task:scheduled ref="myTask1" method="run" cron="0 0/59 11-23 * * ?"/> <task:scheduled ref="myTask2" method="run" cron="0/10 * * * * ?"/> <task:scheduled ref="myTask3" method="run" cron="0/10 * * * * ?"/> </task:scheduled-tasks>
參考資料:http://blog.csdn.net/loongshawn/article/details/50663393