0

我正在 Thorntail 中编写一个计划任务,该任务将运行很长时间(大约 30 分钟)。但是,Thorntail 似乎将执行时间限制为 30 秒。

我的代码如下所示(我删除了我认为不相关的代码):

@Singleton
public class ReportJobProcessor {

    @Schedule(hour = "*", minute = "*/30", persistent = false)
    public void processJobs() {
        // Acquire a list of jobs

        jobs.forEach(this::processJob);
    }

    private void processJob(ReportJob job) {
        // A long running process
    }
}

30 秒后,我在日志中看到以下内容:

2019-10-01 16:15:14,097 信息 [org.jboss.as.ejb3.timer](EJB 默认 - 2)WFLYEJB0021:计时器:[id=...timedObjectId=...自动计时器?:真持久?:false timerService=org.jboss.as.ejb3.timerservice.TimerServiceImpl@42478b98 initialExpiration=null intervalDuration(in milli sec)=0 nextExpiration=Tue Oct 01 16:20:00 CEST 2019 timerState=IN_TIMEOUT info=null]重试

又过了 30 秒,由于作业仍未完成,引发异常。

我不知道如何增加超时,谷歌搜索我的问题没有任何帮助。

如何将超时时间增加到 30 秒以上?

4

1 回答 1

1

我建议你采取一些不同的方法。

计划任务会将作业分发到异步运行的无状态会话 bean (SLSB) ReportJobExecutor,并在作业分发后立即完成而不会超时。同时运行的 SLSB 的数量可以在 中进行调整project-defaults.yml,默认计数为 16,IIRC。这是一个非常基本的示例,但演示了使用 EJB Timer 调用的预定义 bean 池的 Java EE 执行。更复杂的例子是执行器的手动池化,这将允许您控制执行器的生命周期(例如,在指定时间后杀死它们)。

@Singleton
public class ReportJobProcessor {

    @Inject ReportJobExecutor reportJobExecutor;

    @Schedule(hour = "*", minute = "*/30", persistent = false)
    public void processJobs() {
        // Acquire a list of jobs

        jobs.forEach(job -> reportJobExecutor.run(job));
    }
}

@Stateless
@Asynchronous
public class ReportJobExecutor {

    public void run(ReportJob job) {
        //do whatever with job
    }
}

想法 #2:另一种方法是使用 Java Batch Processing API (JSR 352),不幸的是,我不熟悉这个 API。

于 2019-10-17T16:26:24.003 回答