我已經安裝了多臺服務器運行的一個@Schedule
,它們運行向用戶發送電子郵件的彈簧批處理作業。我想確保只有一個此作業的實例運行在多個服務器上。跨多個服務器執行單個作業
基於this問題 我已經實現了一些邏輯,看看它是否可能解決這個問題,只使用spring批處理。
運行我創建了一個輔助類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);
}
這是一個多服務器的有效解決方案s etup?如果不是,有什麼選擇?
編輯1
我做更多的測試 - 設置其運行每5秒一個@Schedule
發起使用我創建的輔助類工作的兩個應用程序。看來我的解決方案不能解決問題。下面是從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提供的方法,我已經得到了類似的結果。
您能解釋一下在上述情況下不起作用嗎?你是說同時運行同一項工作的多次執行? – DevG
是的,兩臺服務器同時啓動相同的作業,即使它仍在其中一個節點上運行/啓動。 – Edd