2013-07-28 7 views
26

У нас есть веб-приложение Spring 3 на Tomcat 6, которое использует несколько плановых услуг через @Scheduled (в основном для работы, которые работают каждую ночь). Теперь кажется, что иногда (редко, возможно, раз в два месяца или около того) поток планировщика перестает работать, поэтому ни одно из заданий не будет выполнено в следующую ночь. В наших файлах журналов нет исключений или регистрации.Spring Scheduler неожиданно останавливается

Неужели кто-нибудь подсказывает, почему это происходит? Или как получить дополнительную информацию об этой проблеме?

Есть ли способ обнаружить эту ситуацию в приложении и перезапустить планировщик?

В настоящее время мы решаем это, имея также задание на ведение журнала, которое выполняется каждые 5 минут и создает запись в журнале. Если файл журнала перестает обновляться (контролируется nagios), мы знаем, что пришло время перезагрузить tomcat. Было бы неплохо перезапустить задания без полного перезапуска сервера.

+6

Какова работа, выполняемая в запланированных задачах? Возможно ли, что что-то застряло в бесконечном цикле? Я спрашиваю, потому что запланированные задачи по умолчанию используют threadpool из 1 потока, и если он каким-то образом зависает, ваши будущие задачи не будут запущены (но я уверен, что они будут поставлены в очередь). –

+0

@ nicholas.hauschild Он вызывает внешний веб-сервис REST. Итак, вы говорите, что такой запрос может блокировать (тупик?) И, следовательно, останавливать все остальные задания. Я думаю, что я попрошу сброс потока сервера, если это произойдет снова. Спасибо за ваш вклад. – obecker

+0

Возьмем дамп потока, вероятно, будет хорошей идеей. –

ответ

3

Это довольно легко узнать. Вы будете делать это со стеком. Есть много сообщений о том, как получить трассировку стека, в системе unix, которую вы делаете «kill -3», и трассировка стека появляется в файле журнала catalina.out.

Как только у вас есть трассировка стека, найдите поток планировщика и посмотрите, что он делает. Возможно ли, что задача, которую она выполняла, застряла?

Вы также можете отправить трассировку стека здесь для получения дополнительной помощи.

Важно знать, какой планировщик вы используете. если вы используете SimpleAsyncTaskExecutor, он запустит новый поток для каждой задачи, и ваше планирование никогда не завершится. Однако, если у вас есть задачи, которые не закончены, у вас в конечном итоге закончится нехватка памяти.

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

+0

Спасибо, что дамп потока уже был предложен nicolas.hausschild, и я нашел заблокированный HTTP-вызов из службы REST. Я обновил библиотеку HttpClient, и мне интересно, может ли это решить проблему уже. – obecker

9

Поскольку этот вопрос получил так много голосов, я выложу то, что (вероятно, очень специфично) решение моей проблемы было.

Мы используем библиотеку 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

Я столкнулся с ТОЧНОЙ проблемой с использованием Apache HttpClient ... Вы, мой друг, джентльмен и ученый! – nterry

+0

Это действительно была моя проблема, в частности, использовала Джерси с ApacheConnector, настроенным с помощью PoolingHttpClientConnectionManager. Крайне важно установить параметр ** connectionRequestTimeout **, поскольку пул может зависать бесконечно, если он не установлен. Для этого вы должны установить его в RequestConfig и установить всю конфигурацию запроса в конфигурации клиента соединителя следующим образом: 'RequestConfig rc = RequestConfig.custom(). SetConnectTimeout (2000) .setSocketTimeout (2000) .setConnectionRequestTimeout (200) .build(); clientConfig.property (ApacheClientProperties.REQUEST_CONFIG, rc); ' – David

Смежные вопросы