【问题标题】:Quartz job completed but the thread remains blockedQuartz 作业已完成,但线程仍处于阻塞状态
【发布时间】:2016-12-22 13:40:19
【问题描述】:

我有这样的 Quartz Job

@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class MyJob{

     public void execute(JobExecutionContext jec) throws JobExecutionException {
         //connect to a FTP server, monitor directory for new files and download
         //Using FTPClient of commons-net-3.5.jar 
     }

作业被触发

JobDetail jobDetail = newJob(MyJob.class)
    .withIdentity(jobName, DEFAULT_GROUP)
    .usingJobData(new JobDataMap(jobProperties))
    .build();   

//trigger every minute                  
Trigger trigger = newTrigger()
    .withIdentity(jobName, DEFAULT_GROUP)
    .startNow()
    .withSchedule(cronSchedule(cronExpression))
    .build();

scheduler.scheduleJob(jobDetail,trigger);

作业每分钟触发一次。它可以正常运行大约 1 周(10000 次执行)并且莫名其妙地不会重新启动。日志中没有错误,看到它已经完成了之前的执行。其他进程正在正确触发。

将库升级到 quartz-2.2.3commons-net-3.5(寻找 FTP 库中可能存在的错误)我设法持续了 3 周

我有一个 Job 来监视 Scheduler,它说触发状态是 BLOCKED。被阻塞进程的Thread 未被应用服务器重用

 TriggerState triggerState = scheduler.getTriggerState(triggerKey);

我还没有找到关于 Quartz 这类问题的文档,所以我怀疑是 FTP 库中的一个错误,它会干扰石英启动的线程,例如使用 @PersistJobDataAfterExecution

我想知道这是一个已知问题还是可能是一个错误,所以我可以应用解决方案或解决方法(杀死石英作业 how to stop/interrupt quartz scheduler job manually

【问题讨论】:

  • 它总是在相同的执行或时间失败?作业分配了哪种模式?
  • 失败时间从 3 天到 3 周不等(4300 - 30000 次执行),但偶尔会在 24 小时内失败。通常在空执行后失败:FTP 连接、无文件、断开连接。 cron 表达式为:0 0/1 * * * ?
  • 也许这个空执行会抛出任何可能影响 cron 的未处理异常或错误?模式和工作似乎以正确的方式创建......
  • 感谢@JordiCastilla 的回答。在最后的更改中,我添加了一个日志行作为执行方法的最后一步,并用大 try/catch/finally 包围,以确保没有未捕获的异常。我还查看了应用程序服务器日志以寻找丢失的异常,但没有运气。我认为如果是异常,进程将失败,但不会保持线程阻塞(不再使用 Java thread)。也许石英的最后一个动作(PersistJobDataAfterExecution)因任何原因被阻止。

标签: java multithreading ftp quartz-scheduler


【解决方案1】:

经过几个月的服务偶尔中断并怀疑 FTP 连接错误阻塞了服务,我们终于实施了一项似乎可以解决问题的措施

每个流程现在执行:

FTPClient ftp = new FTPClient();

//Added connection timeout before connect()
ftp.setDefaultTimeout(getTimeoutInMilliseconds());  

ftp.connect(host, port);

//Added more timeouts to see if thread locks disappear...
ftp.setBufferSize(1024 * 1024);
ftp.setSoTimeout(getTimeoutInMilliseconds());   

奇怪的是在connect()之前进程并没有被阻塞,进程继续并结束没有重新启动,但是设置超时时问题没有再次发生

【讨论】:

    猜你喜欢
    • 2020-07-14
    • 2013-11-27
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-17
    • 2021-12-26
    • 1970-01-01
    相关资源
    最近更新 更多