2016-08-25 13 views
5

複数のサーバーで、ユーザーに電子メールを送信するバッチ・バッチ・ジョブを実行する@Scheduleを実行するセットアップがあります。私は、このジョブの1つのインスタンスだけが複数のサーバーにわたって実行されていることを確認したいと思います。複数のサーバー間での単一ジョブの実行

this質問 私は春のバッチを使用してこれを解決する可能性があるかどうかを確認するロジックを実装しました。

私は、次のメソッドを持つヘルパークラスJobRunnerを作成したジョブを実行するには:

public void run(Job job) { 
    try { 
     jobLauncher.run(job, new JobParameters()); 
    } catch (JobExecutionAlreadyRunningException e) { 

     // Check if job is inactive and stop it if so. 
     stopIfInactive(job); 

    } catch (JobExecutionException e) { 
     ... 
    } 
} 

stopIfInactive方法:

private void stopIfInactive(Job job) { 
    for (JobExecution execution : jobExplorer.findRunningJobExecutions(job.getName())) { 
     Date createTime = execution.getCreateTime(); 

     DateTime now = DateTime.now(); 

     // Get running seconds for more info. 
     int seconds = Seconds 
       .secondsBetween(new DateTime(createTime), now) 
       .getSeconds(); 

     LOGGER.debug("Job '{}' already has an execution with id: {} with age of {}s", 
       job.getName(), execution.getId(), seconds); 

     // If job start time exceeds the execution window, stop the job. 
     if (createTime.before(now.minusMillis(EXECUTION_DEAD_MILLIS) 
       .toDate())) { 

      LOGGER.warn("Execution with id: {} is inactive, stopping", 
        execution.getId()); 

      execution.setExitStatus(new ExitStatus(BatchStatus.FAILED.name(), 
        String.format("Stopped due to being inactive for %d seconds", seconds))); 

      execution.setStatus(BatchStatus.FAILED); 
      execution.setEndTime(now.toDate()); 

      jobRepository.update(execution); 
     } 
    } 
} 

そしてジョブは、すべてのサーバー上で以下で実行されています。

@Scheduled(cron = "${email.cron}") 
public void sendEmails() { 
    jobRunner.run(emailJob); 
} 

これは、複数のサーバーetup?そうでない場合、代替案は何ですか?

EDIT 1

私は少しより多くのテストでしてきました - セットアップ@Schedule 5秒ごとに実行する二つのアプリケーション、私が作成したヘルパークラスを使用してジョブを開始します。私の解決策は問題を解決しないようです。ここでは春のバッチで使用されbatch_job_executionテーブルからのデータです:

job_execution_id | version | job_instance_id |  create_time  |  start_time  |  end_time   | status | exit_code | exit_message |  last_updated  | job_configuration_location 
------------------+---------+-----------------+-------------------------+-------------------------+-------------------------+-----------+-----------+--------------+-------------------------+---------------------------- 
      1007 |  2 |    2 | 2016-08-25 14:43:15.024 | 2016-08-25 14:43:15.028 | 2016-08-25 14:43:16.84 | COMPLETED | COMPLETED |    | 2016-08-25 14:43:16.84 | 
      1006 |  1 |    2 | 2016-08-25 14:43:15.021 | 2016-08-25 14:43:15.025 |       | STARTED | UNKNOWN |    | 2016-08-25 14:43:15.025 | 
      1005 |  2 |    2 | 2016-08-25 14:43:10.326 | 2016-08-25 14:43:10.329 | 2016-08-25 14:43:12.047 | COMPLETED | COMPLETED |    | 2016-08-25 14:43:12.047 | 
      1004 |  2 |    2 | 2016-08-25 14:43:10.317 | 2016-08-25 14:43:10.319 | 2016-08-25 14:43:12.03 | COMPLETED | COMPLETED |    | 2016-08-25 14:43:12.03 | 
      1003 |  2 |    2 | 2016-08-25 14:43:05.017 | 2016-08-25 14:43:05.02 | 2016-08-25 14:43:06.819 | COMPLETED | COMPLETED |    | 2016-08-25 14:43:06.819 | 
      1002 |  2 |    2 | 2016-08-25 14:43:05.016 | 2016-08-25 14:43:05.018 | 2016-08-25 14:43:06.811 | COMPLETED | COMPLETED |    | 2016-08-25 14:43:06.811 | 
      1001 |  2 |    2 | 2016-08-25 14:43:00.038 | 2016-08-25 14:43:00.042 | 2016-08-25 14:43:01.944 | COMPLETED | COMPLETED |    | 2016-08-25 14:43:01.944 | 
      1000 |  2 |    2 | 2016-08-25 14:43:00.038 | 2016-08-25 14:43:00.041 | 2016-08-25 14:43:01.922 | COMPLETED | COMPLETED |    | 2016-08-25 14:43:01.922 | 
       999 |  2 |    2 | 2016-08-25 14:42:55.02 | 2016-08-25 14:42:55.024 | 2016-08-25 14:42:57.603 | COMPLETED | COMPLETED |    | 2016-08-25 14:42:57.603 | 
       998 |  2 |    2 | 2016-08-25 14:42:55.02 | 2016-08-25 14:42:55.023 | 2016-08-25 14:42:57.559 | COMPLETED | COMPLETED |    | 2016-08-25 14:42:57.559 | 
(10 rows) 

私も@Palcenteによって提供される方法は、私は同様の結果を持ってみました。

+0

上記のケースでは何が動作しないのか説明できますか?あなたは、同じ仕事の複数の実行が同時に実行されていることを意味しますか? – DevG

+0

はい、両方のサーバーが同じジョブを同時に起動します。ただし、ノードがまだ稼働していても、ノードの1つで起動しています。 – Edd

答えて

0

Spring Integrationの最新リリースでは、分散ロックの機能が追加されました。これは本当に1つのサーバーだけがジョブを起動するようにするために使用するものです(ロックを取得したサーバーのみがジョブを起動する必要があります)。 Spring Integrationのロック機能の詳細については、こちらのドキュメントを参照してください。http://projects.spring.io/spring-integration/

+0

java-configを使用してこの機能を示すドキュメントやspring-integration-samples(https://github.com/spring-projects/spring-integration-samples)プロジェクトのサンプルを見つけることができません。現時点では、単純なロックテーブルの作成を考えています。 – Edd

関連する問題