Java Quartz作业已完成,但线程仍被阻塞
我有一份像这样的工作Java Quartz作业已完成,但线程仍被阻塞,java,multithreading,ftp,quartz-scheduler,Java,Multithreading,Ftp,Quartz Scheduler,我有一份像这样的工作 @PersistJobDataAfterExecution @DisallowConcurrentExecution public class MyJob{ public void execute(JobExecutionContext jec) throws JobExecutionException { //connect to a FTP server, monitor directory for new files and downlo
@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.3
和commons-net-3.5
(查找FTP库中可能存在的错误)我设法维持了3周
我有一个作业
来监视调度程序
,它说触发器状态是阻塞的
。被阻止进程的线程
未被应用程序服务器重用
TriggerState triggerState = scheduler.getTriggerState(triggerKey);
我没有发现有关Quartz这类问题的文档,因此我怀疑FTP库中存在一个bug,它干扰了Quartz启动的线程,例如使用@PersistJobDataAfterExecution
我想知道这是一个已知的问题还是一个bug,因此我可以应用一个解决方案或解决方法(终止quartz作业)在几个月偶尔出现服务中断,并怀疑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()
中没有被阻止,进程继续并结束,没有重新启动,但设置超时时,问题没有再次发生它总是在相同的执行或时间内失败?作业分配了哪种模式?失败时间在3天到3周之间(4300-30000次执行),但偶尔会在24小时内失败。通常在空执行后失败:FTP连接、无文件、断开连接。cron表达式是:0 0/1***?
此空执行是否会引发任何可能影响cron的未经处理的异常或错误?模式和工作似乎是以正确的方式创建的……感谢您的回答@JordiCastilla。在上一个更改中,我添加了一个日志行作为执行方法的最后一步,并用一个大的try/catch/finally
来确保没有未修补的异常。此外,我还查看了应用程序服务器日志,查找丢失的异常,但运气不佳。我认为如果这是一个异常,进程将失败,但不会保持线程阻塞(不再使用Javathread
)。quartz的最后一个操作(PersistJobDataAfterExecution
)可能由于任何原因被阻止。