我们在Tomcat 6上有一个Spring 3 Web应用程序,它通过@Scheduled
使用多个计划服务(主要用于每晚运行的作业)。现在似乎有时(很少,也许在两个月左右)调度程序线程停止工作,因此在第二天晚上不会执行任何作业。我们的日志文件中没有异常或日志记录条目。
有人知道为什么会这样吗?或者如何获得有关此问题的更多信息?
有没有办法在应用程序中检测这种情况并重新启动调度程序?
目前,我们通过每5分钟运行一次日志记录作业并创建日志条目来解决此问题。如果日志文件停止更新(由nagios监视),我们知道是时候重启tomcat了。如果没有完整的服务器重启,重启作业会很不错。
答案 0 :(得分:14)
由于这个问题获得了如此多的选票,我将发布我的问题的(可能是非常具体的)解决方案。
我们正在使用Apache HttpClient库来调用预定作业中的远程服务。不幸的是,执行请求时没有设置默认超时。设置后
connectTimeout
connectionRequestTimeout
socketTimeout
问题消失了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();
答案 1 :(得分:3)
这很容易找到。您将使用堆栈跟踪执行此操作。有很多关于如何获得堆栈跟踪的帖子,在unix系统上你做'kill -3'并且堆栈跟踪出现在catalina.out日志文件中。
一旦有了堆栈跟踪,找到调度程序线程并查看它在做什么。它正在执行的任务是否可能卡住了?
您也可以在此处发布堆栈跟踪以获取更多帮助。
重要的是要知道您使用的调度程序。如果你使用SimpleAsyncTaskExecutor,它将为每个任务启动一个新线程,你的调度永远不会失败。但是,如果您的任务没有完成,最终会耗尽内存。
http://docs.spring.io/spring/docs/3.0.x/reference/scheduling.html
答案 2 :(得分:-1)
就我而言,堆栈跟踪是绝对干净的,线程仅启动了几次,仅此而已。问题出在另一个时间表上。
已更新
计划无法正常运行,因为我使用fixedDelayString
并且以前的工作在开始新工作时没有结束。将时间表更改为fixedRateString
后,线程将正确启动。