xxl-job oom后scheduleThread线程停止,自动任务不再执行

um6iljoc  于 4个月前  发布在  其他
关注(0)|答案(1)|浏览(63)

Please answer some questions before submitting your issue. Thanks!

Which version of XXL-JOB do you using?

2.2.1版本

Expected behavior

自动任务正常运行

Actual behavior

上周突然生产环境突然碰到每5分钟执行的任务,很久没有执行了,而且排查了xxl-job admin的日志,日志中也没有相关的报错,所以很疑惑,随后排查了调度器的内存与CPU均未发现问题,的网络是OK的,数据库也是正常的,手动执行相关任务也是成功的,随后将xxl-job调度器重启后任务正常执行。

Steps to reproduce the behavior

因为手动执行任务正常,所以排查自动任务的执行入口,阅读JobScheduleHelper相关源码,项目启动后开启scheduleThread线程,每隔1s去数据库拉取未来5s要执行的job添加到待执行队列中,所以自动任务没执行,而手动任务可以正常执行,极大可能是scheduleThread 线程挂了。

scheduleThread 中只有这一异常处理,但是查询调度器日志文件没发现改异常,那么进一步怀疑调度器jvm 出现 oom了,抛出的是Error,所以没被catch到,导致扫描任务退出所以自动任务不再执行(由于当时的调取器运行jvm启动参数未加入oom dump指令,也就没有发现dump的堆文件,所以猜测是出现了oom,建议大家加上该指令。)

示例代码

public class ThreadTest {

    private static volatile boolean scheduleThreadToStop = false;

    private static volatile boolean ringThreadToStop = false;

    public static void main(String[] args) throws Exception {
        // 每间隔1s支持一次,输出 AAAAA 
        Thread scheduleThread = new Thread(() -> {
            while (!scheduleThreadToStop) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    doSomething();
                } catch (Exception e) {
                    System.err.println(e.getMessage());
                }
            }
        });
        // 每间隔1s支持一次,输出 BBBBB 
        Thread ringThread = new Thread(() -> {
            while (!ringThreadToStop) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("BBBBB");
            }
        });
        scheduleThread.setDaemon(true);
        ringThread.setDaemon(true);
        scheduleThread.start();
        ringThread.start();
        scheduleThread.join();
        ringThread.join();
    }

    public static void doSomething() {
        // 随机出现OOM Error
        if (RandomUtil.randomBoolean()) {
            throw new Error("系统OOM了");
        }
        System.err.println("AAAAA");
    }
}

运行结果如下:

系统抛出Error后未被捕获,导致scheduleThread线程退出循环不再工作,ringThread线程照常运行。

Other information

jvm出现OOM后触发OOM的线程会直接销毁其他线程会照常运行,系统还是能正常运行,所以能不能将catch范围放大到Throwable,这样即使出现oom当前未执行的任务直接抛弃掉,后续任务还能自动运行,降低故障影响。

yruzcnhs

yruzcnhs1#

抱歉!上面的版本号填错了,目前使用的版本应该是:2.1.1

相关问题