2016-08-25 24 views
5

Birden çok sunucunun, kullanıcılara e-posta gönderen bir yaylı toplu iş çalıştırması olan bir @Schedule çalıştırdığı kurulumum var. Bu işin yalnızca bir örneğinin birden fazla sunucuda çalıştırıldığından emin olmak istiyorum.Birden çok sunucuda tek iş yürütme

this sorularına göre Sadece bahar serisini kullanarak bunu çözmenin mümkün olup olmadığını görmek için bazı mantık yürütüyorum.

aşağıdaki yöntemleri ile bir yardımcı sınıf JobRunner oluşturulan bir iş çalıştırmak için:

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 yöntemi:

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); 
     } 
    } 
} 

Ve sonra işler tüm sunucularda izleyerek ran gibidir:

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

Bu, birden çok sunucu için geçerli bir çözüm s etup? Değilse, alternatifler nelerdir?

DÜZENLEME 1

biraz daha test yaptım ettik - kurulum oluşturduğum yardımcı sınıf kullanarak bir işi başlatan @Schedule her 5 saniyede koşmak iki uygulama. Benim çözümüm sorunu çözmüyor gibi görünüyor. Ayrıca @Palcente tarafından sağlanan yöntem, ben benzer sonuçlar var çalıştı

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) 

: Burada yay toplu tarafından kullanılan batch_job_execution tablodan veridir.

+0

Yukarıdaki örnekte neyin çalışmadığını açıklayabilir misiniz? Aynı işin birden çok yürütmesinin aynı anda çalıştırıldığı anlamına mı geliyor? – DevG

+0

Evet, her iki sunucu da aynı işi, aynı zamanda, düğümlerden biri üzerinde çalışıyor olsa bile başlatır. – Edd

cevap

0

Spring Integration'ın en son sürümü dağıtılmış kilitler etrafında bazı işlevler ekledi. Bu, yalnızca bir sunucunun işi başlattığından emin olmak için kullanmak istediğiniz şeydir (yalnızca kilidi alan sunucu işi başlatmalıdır). Spring Integration'ın kilitleme yetenekleri hakkında daha fazla bilgiyi şu belgede bulabilirsiniz: http://projects.spring.io/spring-integration/

+0

Bu işlevselliği java-config kullanarak gösteren belgeler veya yay tümleştirme örnekleri (https://github.com/spring-projects/spring-integration-samples) projesiyle ilgili örnekler bulamıyorum. Şu anda basit bir kilit tablosu oluşturmayı düşünüyorum. – Edd

İlgili konular