2013-07-28 5 views
26

Tomcat 6には、@Scheduled(主に毎晩実行するジョブ用)を介して複数のスケジュールされたサービスを使用するSpring 3 Webアプリケーションがあります。今では、スケジューラースレッドが動作を停止することはまれである(たぶんおそらく2ヶ月に1回程度)ので、次の夜は実行されません。ログファイルには例外やログエントリはありません。Spring Schedulerが突然停止する

これはなぜ起こっているのか誰かが分かっていますか?またはこの問題に関する詳細情報の入手方法は?

アプリケーション内でこの状況を検出し、スケジューラを再起動する方法はありますか?

現在のところ、5分ごとに実行されるログジョブを作成し、ログエントリを作成することでこれを解決しています。ログファイルが更新されなくなった場合(nagiosによって監視されます)、tomcatを再起動する必要があります。サーバーを完全に再起動しなくてもジョブを再起動するといいでしょう。

+6

スケジュールされたタスクでは何が行われていますか?何かが無限ループに詰まってしまう可能性はありますか?スケジュールされたタスクはデフォルトで1スレッドのスレッドプールを使用していて、何とか掛かってしまえば、将来のタスクは開始されないため、私は尋ねます。(しかし、キューに入れられると確信しています。 –

+0

@ nicholas.hauschild外部REST Webサービスを呼び出します。つまり、そのような要求がブロックされ(デッドロック?)、他のすべてのジョブを停止する可能性があるということです。私はこれが再び発生した場合、私はサーバーのスレッドダンプを要求すると思います。あなたのご意見ありがとうございます。 – obecker

+0

スレッドダンプを取ることはおそらく良い考えです。 –

答えて

3

これはかなりわかりやすいです。これはスタックトレースで行います。スタックトレースを取得する方法については多くの記事がありますが、unixシステムでは 'kill -3'とスタックトレースがcatalina.outログファイルに表示されます。

スタックトレースを取得したら、スケジューラスレッドを見つけて何が実行されているかを確認します。実行していたタスクが停止している可能性はありますか?

また、ここでスタックトレースを送信して詳細なヘルプを表示することもできます。

重要なことは、どのスケジューラを使用するかです。 SimpleAsyncTaskExecutorを使用すると、タスクごとに新しいスレッドが開始され、スケジューリングが失敗することはありません。ただし、完了していないタスクがあると、最終的にメモリ不足になります。

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

+0

ありがとうございます - スレッドダンプを取ることは既にnicolas.hausschildによって提案されており、RESTサービスからブロックされたHTTPコールを見つけました。私は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

これは確かに私の問題でした。具体的には、PoolingHttpClientConnectionManagerで設定されたApacheConnectorでJerseyを使用していました。 ** connectionRequestTimeout **パラメータを設定することが重要です。これが設定されていない場合、プールは無期限にハングアップする可能性があります。これを行うには、RequestConfigに設定して、コネクタクライアントのコンフィグレーションでrequest config全体を以下のように設定する必要があります。 RequestConfig rc = RequestConfig.custom().setConnectTimeout(2000).setSocketTimeout(2000).setConnectionRequestTimeout 200).build(); clientConfig.property(ApacheClientProperties.REQUEST_CONFIG、rc); ' – David