本文引用了谷粒商城的課程
定時(shí)任務(wù)
定時(shí)任務(wù)是我們系統(tǒng)里面經(jīng)常要用到的一些功能。如每天的支付訂單要與支付寶進(jìn)行對(duì)賬操作、每個(gè)月定期進(jìn)行財(cái)務(wù)匯總、在服務(wù)空閑時(shí)定時(shí)統(tǒng)計(jì)當(dāng)天所有信息數(shù)據(jù)等。
定時(shí)任務(wù)有個(gè)非常流行的框架Quartz和Java原生API的Timer類(lèi)。Spring框架也可以支持定時(shí)任務(wù)。
cron表達(dá)式
語(yǔ)法:秒 分 時(shí) 日 月 周 年(Spring 不支持)
http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html
特殊字符:
,:枚舉: (cron=“7,9,23 * * * * ?”):任意時(shí)刻的 7,9,23 秒啟動(dòng)這個(gè)任務(wù);
-:范圍: (cron=“7-20 * * * * ?”):任意時(shí)刻的 7-20 秒之間,每秒啟動(dòng)一次
()* :任意;指定位置的任意時(shí)刻都可以
/:步長(zhǎng); (cron=“7/5 * * * * ?”):第 7 秒啟動(dòng),每 5 秒一次;(cron=“/5 * * * * ?“):任意秒啟動(dòng),每 5 秒一次;
?:(出現(xiàn)在日和周幾的位置):為了防止日和周沖突,在周和日上如果要寫(xiě)通配符使用?(cron=” * * 1 * ?”):每月的 1 號(hào),啟動(dòng)這個(gè)任務(wù);
L:(出現(xiàn)在日和周的位置)”, last:最后一個(gè) (cron=“* * * ? * 3L”):每月的最后一個(gè)周二
W:Work Day:工作日 (cron=“* * * W * ?”):每個(gè)月的工作日觸發(fā) (cron=“* * * LW * ?”):每個(gè)月的最后一個(gè)工作日觸發(fā)
#:第幾個(gè) (cron=“* * * ? * 5#2”):每個(gè)月的第 2 個(gè)周 4
注意:日和周幾通常會(huì)發(fā)生沖突,如果日定了,那么周就要使用?通配符
可以在線(xiàn)生成cron表達(dá)式
https://cron.qqe2.com/
cron實(shí)例
SpringBoot整合
* 1、Spring中6位組成,不允許第7位的年
* 2、在周幾的位置,1-7代表周一到周日:MON-SUN
測(cè)試代碼如下
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 定時(shí)任務(wù)
* 1、@EnableScheduling開(kāi)啟定時(shí)任務(wù)
* 2、@scheduled 開(kāi)啟一個(gè)定時(shí)任務(wù)
* **/
@EnableScheduling
@Component
@Slf4j
public class HelloSchedule {
@Scheduled(cron = "*/5 * * * * 4")
public void hello(){
log.info("hello.....");
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
但是這里存在一個(gè)問(wèn)題
定時(shí)任務(wù)不應(yīng)該阻塞,默認(rèn)是阻塞的。(也就是要等業(yè)務(wù)執(zhí)行完,定時(shí)任務(wù)才能開(kāi)始執(zhí)行)
可以使用以下幾種解決方案
1)、CompletableFuture.runAsync()可以讓業(yè)務(wù)以異步的方式,自己提交到線(xiàn)程池
2)、支持定時(shí)任務(wù)線(xiàn)程池設(shè)置:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-414498.html
spring.task.scheduling.pool.size=5
3)、讓定時(shí)任務(wù)異步執(zhí)行
通常是采用第3種方案
開(kāi)啟異步定時(shí)任務(wù)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-414498.html
- 異步任務(wù)
1、@EnableAsycn:開(kāi)啟異步任務(wù)功能
2、@Async 給希望異步執(zhí)行的方法上標(biāo)注上注解
3、自動(dòng)配置類(lèi) TaskExecutionAutoConfiguration 屬性綁定在TaskExecutionProperties
4、.配置定時(shí)任務(wù)的線(xiàn)程池屬性:
spring.task.execution.pool.core-size=5
spring.task.execution.pool.max-size=30
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 定時(shí)任務(wù)
* 1、@EnableScheduling開(kāi)啟定時(shí)任務(wù)
* 2、@scheduled 開(kāi)啟一個(gè)定時(shí)任務(wù)
* 異步任務(wù)
* 1、@EnableAsycn:開(kāi)啟異步任務(wù)功能
* 2、@Async 給希望異步執(zhí)行的方法上標(biāo)注上注解
* 3、自動(dòng)配置類(lèi) TaskExecutionAutoConfiguration 屬性綁定在TaskExecutionProperties
* 4.配置:
* spring.task.execution.pool.core-size=5
* spring.task.execution.pool.max-size=30
* **/
@EnableScheduling
@Component
@Slf4j
@EnableAsync
public class HelloSchedule {
/**
* 1、Spring中6位組成,不允許第7位的年
* 2、在周幾的位置,1-7代表周一到周日:MON-SUN
* 3、定時(shí)任務(wù)不應(yīng)該阻塞,默認(rèn)是阻塞的。(也就是要等業(yè)務(wù)執(zhí)行完,定時(shí)任務(wù)才能開(kāi)始執(zhí)行)
* 1)、CompletableFuture.runAsync()可以讓業(yè)務(wù)以異步的方式,自己提交到線(xiàn)程池
* 2)、支持定時(shí)任務(wù)線(xiàn)程池設(shè)置:
* spring.task.scheduling.pool.size=5
* 3)、讓定時(shí)任務(wù)異步執(zhí)行
*
* 解決:使用異步+定時(shí)任務(wù)來(lái)完成定時(shí)任務(wù)不阻塞的功能。
* **/
@Async
@Scheduled(cron = "*/5 * * * * 4")
public void hello(){
log.info("hello.....");
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
到了這里,關(guān)于分布式定時(shí)任務(wù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!