美文网首页
CountDownLatch的一次线上问题事故排查

CountDownLatch的一次线上问题事故排查

作者: liyang_hawk | 来源:发表于2020-06-21 11:27 被阅读0次

现象

功能:定时任务,每半个小时就执行一次。
现象:在某一天停止触发了。

CheckAutoDeployJob.java
    /**
     * 每小时的30分,零秒触发
     */
    @Scheduled(cron = "0 30 * * * ?")
    public void work() {
          // todo
          logger.info("触发自动续期检查:===" + new Date());
          ...
    }

排查过程

线上机器日志排查

grep "触发自动续期检查" /opt/ione/logs/ione-info.log
image.png

日志分析

  1. 2020-06-11 20:30:00这个时间后,就没有触发了。
  2. 检查其他定时任务是否正常运行。(这个考虑后续证明无需验证)
  3. 查看所有线上其他机器是否也卡在了这个时间。(其他机器的定时任务卡主的时间点不一样)

线上的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)
...

结合代码

查找EnvConfigService-doDeploy方法

CountDownLatch countDownLatch = new CountDownLatch(n);
for (...) {
...
countDownLatch.countDown();
}
countDownLatch.await();

这样,问题就已经定位了。

解决方案

分析原因

countDownLatch.await()会将当前线程持续waiting导致线程一直处于waiting on condition的条件下。

解决方案

countDownLatch.await()因为要一直等待。
使用方式,多线程如果无法countDown。
临时方案:

// 设置countDownLatch默认10分钟超时
countDownLatch.await(10, TimeUnit.MINUTES);

最终方案还是要定位countDown为何不生效的原因。以上只是让程序能做个兼容处理。

解决后的验证

image.png

思考

countdownlatch的使用场景

有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行的。

多线程的顺序执行的方式

个人使用方式和偏好。future和callable组合。代码好理解,异常可捕捉和抛出。
关于其他的方式,待仔细研究后再定论了。

相关文章

网友评论

      本文标题:CountDownLatch的一次线上问题事故排查

      本文链接:https://www.haomeiwen.com/subject/flmoxktx.html