web-dev-qa-db-ja.com

Quartz Schedulerが突然実行を停止し、例外エラーは発生しません

毎日午後7時に実行されていたクォーツジョブがあります。突然実行に失敗しました。 server.logを確認しましたが、例外はスローされません。誰もが問題になる可能性があることを知っていますか?

前もって感謝します

24
Maven Lee

同様の問題がありましたが、問題は、クォーツプロパティに10スレッドのクォーツデフォルトスレッド数があり、スレッドダンプ*を作成したときに、blocked statに10個のジョブがあることがわかりました。これ以上スレッドを実行できません。

クォーツプロパティのスレッドプール内のスレッド数を増やすためのこの問題の簡単な修正。

実際の修正は、コードをレビューして、10個のブロックされたスレッドがあった理由を知ることでした。

*スレッドダンプを実行するには、次を使用できますkill -3 <Javaプロセス番号>これはスレッドダンプをアプリケーションの標準出力に出力します。つまり、Tomcatを実行している場合はそれが見つかります。 in catalina.outログファイル

12
Ahmed Othman

私の場合、データベースへのオープン接続がありました。利用可能な接続がなくなったとき、私のスレッドは永遠に待機し続けました。他の仕事を始めることができなかったので、何も起こらず、すべてがブロックされたままでした。私のアドバイスは、解放する必要があるかもしれないブロッキングリソースがあるかどうかを確認することです。

8
Luismi Lainez

データベースを使用してジョブを保存している場合は、トリガーのtrigger_stateを確認してください。現在、同様の問題が発生しています(または少なくとも同様の症状があります)。

1分に1回実行されるジョブは、トリガーを「取得済み」状態のままにし、二度と実行されません。あなたのように、私はログを何も見ていません。

同じ問題の別の原因も見ています。この場合も、ジョブは実行を停止しますが、トリガーは「取得済み」状態ではありません。今のところ原因はわかりません。

私がこれまでに知っていることは、スケジューラスレッドが空きワーカースレッドを待っているということです。すべてのワーカースレッドが、スケジュールを更新するためにセマフォを待機しているようです。ワーカースレッドが何を待機しているかを確認するためのスレッドダンプをまだ取得できていません。

Quartz 1.6.1RC1を実行しています。このバグレポートを参照してください: http://jira.opensymphony.com/browse/QUARTZ-668

それが私が見ているものだと思います。

4
Jon Strayer

ジョブが例外をスローしていないかどうかを確認します。 Jobexeコードをtrycatchブロックに入れて、例外をトレースして問題のトラブルシューティングを行います。

2
juanjo.arana

私も同様の問題を抱えていましたが、残念ながら、上記の答えはどれも私の問題を理解するのに役立ちませんでした。クォーツ-2.3.2バージョンを使用しています。まず第一に、私は他のいくつかに同意します。ほとんどの場合、スケジューラーが起動しないのは、スレッドの競合状態がブロックされ、クリティカルゾーンに入ったスレッドからフラグを取得しようとして、解放されないことが原因です。これは単に一種の悪いコードのにおいがしますが、とにかく、私は他の人がしたのと同じことをもう一度言いたくありません。私が問題を修正する方法をあなたに与えるために私の解決策を考え出したいです。

次のようにCronスケジューラを使用すると仮定して、詳細な例を示します。

これはSimpleJobクラスです

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import Java.util.Date;

public class SimpleJob implements Job {

    private static Logger _log = LoggerFactory.getLogger(SimpleJob.class);

    public SimpleJob() {
    }

    public void execute(JobExecutionContext context)
            throws JobExecutionException {

        // This job simply prints out its job name and the
        // date and time that it is running
        JobKey jobKey = context.getJobDetail().getKey();
        _log.info("SimpleJob says: " + jobKey + " executing at " + new Date());
    }

}

これはあなたのメインクラスです

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

public class CronTriggerExample {

    public void run() throws Exception {
        Logger log = LoggerFactory.getLogger(CronTriggerExample.class);

        log.info("------- Initializing -------------------");

        // First we must get a reference to a scheduler
        JobDetail job = newJob(SimpleJob.class)
                .withIdentity("job1", "group1").build();

        CronTrigger trigger = newTrigger()
            .withIdentity("trigger1", "group1")
            .withSchedule(cronSchedule("10 10/5 * ? * *").withMisfireHandlingInstructionFireAndProceed())
            .build();
        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        scheduler.start();
        scheduler.scheduleJob(job, trigger);
    }

    public static void main(String[] args) throws Exception {

        CronTriggerExample example = new CronTriggerExample();
        example.run();
    }
}

以下のcron式は、毎時の10分から始まる5分ごとの秒10を意味します。

cronSchedule("10 10/5 * ? * *")

ここで最も興味深い部分に気付いた場合は

withMisfireHandlingInstructionFireAndProceed()

これは、トリガーが失火の状況で感じられた場合に問題を解決するための鍵であり、スケジューラーにすぐに起動するように指示します。別の機会は使用することです

withMisfireHandlingInstructionDoNothing()

失火の状況では、スケジューラが設定されている開始時間にcronTriggerが次に起動されます。たとえば、At second:10の場合、毎時の分:10から5分ごとに開始します。

1

私は似ていますが、多少異なる問題を抱えていました。私のスケジューラーは開発環境で正常に実行されています。このスケジューラーでは、トランザクションの更新などのジョブを実行しています。

ビルドを本番環境に移行すると、スケジューラーは正常に実行され、土曜日まですべてが正常でした。土曜日に私のスケジューラーは突然停止しました。アプリサーバー(OC4J)でスケジューラーに関連する例外は見つかりませんでした。

クォーツ-1.5.2バージョンを使用しています。問題の実際の根本原因を追跡できません。

アプリケーションサーバーの起動時にスケジューラーを起動しています。何かがうまくいかない場合、それは動作を停止します。それから私はそれらを始める機会がありません。

もう一度jspリクエストを使用してinitサーブレットを呼び出してスケジューラを起動すると、違いが生じると思います。これは、プロファイルを確認するようなものです(スケジューラーの正常性と、スケジューラーの再起動)。スケジューラーを開始するためのより良いアプローチがある場合は、私に提案してください。

0
venkaiah