java Spring Scheduler 意外停止

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17909404/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 17:54:11  来源:igfitidea点击:

Spring Scheduler stops unexpectedly

javaspringtomcatscheduled-tasks

提问by obecker

We have a Spring 3 web application on Tomcat 6 that uses several scheduled services via @Scheduled(mainly for jobs that run every night). Now it appears that sometimes (rarely, perhaps once in two months or so) the scheduler thread stops working, so none of the jobs will be executed in the following night. There is no exception or logging entry in our log files.

我们在 Tomcat 6 上有一个 Spring 3 Web 应用程序,它使用多个计划服务通过@Scheduled(主要用于每晚运行的作业)。现在看来有时(很少,大概两个月左右)调度程序线程停止工作,因此在接下来的晚上将不会执行任何作业。我们的日志文件中没有例外或日志条目。

Has anybody a clue why this is happening? Or how to get more information about this problem?

有人知道为什么会这样吗?或者如何获得有关此问题的更多信息?

Is there a way to detect this situation within the application and to restart the scheduler?

有没有办法在应用程序中检测这种情况并重新启动调度程序?

Currently we are solving this by having also a logging job that runs every 5 minutes and creates a log entry. If the log file stops being updated (monitored by nagios), we know it is time to restart tomcat. It would be nice to restart the jobs without a complete server restart.

目前,我们正在解决这个问题,它还有一个每 5 分钟运行一次的日志作业并创建一个日志条目。如果日志文件停止更新(由 nagios 监控),我们知道是时候重启 tomcat 了。在没有完全重启服务器的情况下重启作业会很好。

回答by obecker

Since this question got so many votes, I'll post what the (probably very specific) solution to my problem was.

由于这个问题得到了如此多的投票,我将发布我的问题的(可能非常具体的)解决方案是什么。

We are using the Apache HttpClient library to make calls to remote services in the scheduled jobs. Unfortunately there are no default timeouts set when performing requests. After setting

我们正在使用 Apache HttpClient 库来调用预定作业中的远程服务。不幸的是,执行请求时没有设置默认超时。设置后

connectTimeout
connectionRequestTimeout
socketTimeout

to 30 seconds the problem was gone.

到 30 秒,问题就消失了。

int timeout = 30 * 1000; // 30 seconds
RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(timeout)
        .setConnectionRequestTimeout(timeout)
        .setSocketTimeout(timeout).build();
HttpClient client = HttpClients.custom()
        .setDefaultRequestConfig(requestConfig).build();

回答by obecker

This is pretty easy to find out. You would be doing this with a stack trace. There are many posts on how to get a stack trace, on unix system you do 'kill -3 ' and the stack trace appears in the catalina.out log file.

这很容易发现。您将使用堆栈跟踪来执行此操作。有很多关于如何获取堆栈跟踪的帖子,在 unix 系统上您执行“kill -3”,堆栈跟踪出现在 catalina.out 日志文件中。

Once you have a stack trace, find the scheduler thread and see what it is doing. Is it possible that the task it was executing got stuck?

获得堆栈跟踪后,找到调度程序线程并查看它在做什么。它正在执行的任务是否有可能卡住了?

you can also post the stack trace here for more help.

您还可以在此处发布堆栈跟踪以获得更多帮助。

what is important to know is what scheduler you use. if you use the SimpleAsyncTaskExecutor, it will start a new thread for each task, and your scheduling will never fail. However, if you have tasks that don't finish, you will run out of memory eventually.

重要的是要知道您使用的是什么调度程序。如果您使用 SimpleAsyncTaskExecutor,它将为每个任务启动一个新线程,并且您的调度永远不会失败。但是,如果您有未完成的任务,最终会耗尽内存。

http://docs.spring.io/spring/docs/3.0.x/reference/scheduling.html

http://docs.spring.io/spring/docs/3.0.x/reference/scheduling.html

回答by dos4dev

In my case stack trace was absolutely clean, thread started only a couple of time and that's all. The problem was in conflict with another schedule.

在我的情况下,堆栈跟踪绝对干净,线程仅启动了几次,仅此而已。问题与另一个时间表冲突。

Updated

更新

Schedule not work correctly, because I use fixedDelayStringand the previous job not ended when was time to start new. After changed schedule to fixedRateString, threads started correctly.

时间表无法正常工作,因为我使用 fixedDelayString了之前的工作并且没有结束什么时候开始新的工作。将 schedule 更改为 后fixedRateString,线程正确启动。