現(xiàn)象
功能:定時(shí)任務(wù),每半個(gè)小時(shí)就執(zhí)行一次。
現(xiàn)象:在某一天停止觸發(fā)了。
CheckAutoDeployJob.java
/**
* 每小時(shí)的30分,零秒觸發(fā)
*/
@Scheduled(cron = "0 30 * * * ?")
public void work() {
// todo
logger.info("觸發(fā)自動(dòng)續(xù)期檢查:===" + new Date());
...
}
排查過程
線上機(jī)器日志排查
grep "觸發(fā)自動(dòng)續(xù)期檢查" /opt/ione/logs/ione-info.log

image.png
日志分析
- 2020-06-11 20:30:00這個(gè)時(shí)間后,就沒有觸發(fā)了。
- 檢查其他定時(shí)任務(wù)是否正常運(yùn)行。(這個(gè)考慮后續(xù)證明無需驗(yàn)證)
- 查看所有線上其他機(jī)器是否也卡在了這個(gè)時(shí)間。(其他機(jī)器的定時(shí)任務(wù)卡主的時(shí)間點(diǎn)不一樣)
線上的jstack日志排查
> jps
435 spring.jar
> jstack -l 435 > jstack_20200618.out
> grep 'CheckAutoDeployJob' jstack_20200618.out
...
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
at com.bj58.rdm.web.service.env.EnvConfigService.doDeploy(EnvConfigService.java:190)
at com.bj58.rdm.web.service.job.BaseJob.doDeploy(BaseJob.java:134)
at com.bj58.rdm.web.service.job.CheckAutoDeployJob.lambda$triggerAutoDeploy$23(CheckAutoDeployJob.java:72)
at com.bj58.rdm.web.service.job.CheckAutoDeployJob$$Lambda$572/1203642436.accept(Unknown Source)
...
結(jié)合代碼
查找EnvConfigService-doDeploy方法
CountDownLatch countDownLatch = new CountDownLatch(n);
for (...) {
...
countDownLatch.countDown();
}
countDownLatch.await();
這樣,問題就已經(jīng)定位了。
解決方案
分析原因
countDownLatch.await()會(huì)將當(dāng)前線程持續(xù)waiting導(dǎo)致線程一直處于waiting on condition的條件下。
解決方案
countDownLatch.await()因?yàn)橐恢钡却?br>
使用方式,多線程如果無法countDown。
臨時(shí)方案:
// 設(shè)置countDownLatch默認(rèn)10分鐘超時(shí)
countDownLatch.await(10, TimeUnit.MINUTES);
最終方案還是要定位countDown為何不生效的原因。以上只是讓程序能做個(gè)兼容處理。
解決后的驗(yàn)證

image.png
思考
countdownlatch的使用場(chǎng)景
有一個(gè)任務(wù)想要往下執(zhí)行,但必須要等到其他的任務(wù)執(zhí)行完畢后才可以繼續(xù)往下執(zhí)行的。
多線程的順序執(zhí)行的方式
個(gè)人使用方式和偏好。future和callable組合。代碼好理解,異常可捕捉和拋出。
關(guān)于其他的方式,待仔細(xì)研究后再定論了。