Quartz failover in cluster
I'm trying clustered Quartz in a sample Spring Boot 1.5 app.
But I'm very annoyed by the following behavior: when one node fails, the second node takes over the charge of running the task but runs all the executions that were missed.
Here's the full scenario (I have to nodes, strictly identical):
- Start node #1. Node #1 starts executing the task (which is a basic log) every second
- Start node #2. Node #2 does nothing yet.
- Stop node #1. For a few seconds, node #2 does nothing.
- When node #2 decides to begin the execution of the task, it begins with runs 4 or 5 executions of the task in one second.
- After that, the task gets executed every second as usual on node #2.
My guess is that the first executions of the task by node #2 (when I get 4 or 5 runs in only one second) is the run of the "missed" executions (those that would normally have been run between the time node #1 stopped and the time node #2 took over the task).
I would like to skip those first runs and just have node #2 run the task every second.
But apparently, those first executions are not considered by Quartz to be "misfires": I tried all the possible "misfire instructions" but none of them could skip those runs.
Here is how the trigger is created:
public SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail) {
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
factoryBean.setStartDelay(0L);
factoryBean.setRepeatInterval(1000);
factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
// in case of misfire, ignore all missed triggers and continue :
factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
return factoryBean;
}
And here is the Quartz configuration:
org.quartz.scheduler.instanceName=quartz-clustered
org.quartz.scheduler.instanceId=AUTO
org.quartz.threadPool.threadCount=5
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval=5000
# A different classloader is needed to work with Spring Boot dev mode,
# see https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-known-restart-limitations
# and https://github.com/quartz-scheduler/quartz/issues/221
org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.ThreadContextClassLoadHelper
org.quartz.scheduler.skipUpdateCheck=true
spring-boot cluster-computing quartz-scheduler
add a comment |
I'm trying clustered Quartz in a sample Spring Boot 1.5 app.
But I'm very annoyed by the following behavior: when one node fails, the second node takes over the charge of running the task but runs all the executions that were missed.
Here's the full scenario (I have to nodes, strictly identical):
- Start node #1. Node #1 starts executing the task (which is a basic log) every second
- Start node #2. Node #2 does nothing yet.
- Stop node #1. For a few seconds, node #2 does nothing.
- When node #2 decides to begin the execution of the task, it begins with runs 4 or 5 executions of the task in one second.
- After that, the task gets executed every second as usual on node #2.
My guess is that the first executions of the task by node #2 (when I get 4 or 5 runs in only one second) is the run of the "missed" executions (those that would normally have been run between the time node #1 stopped and the time node #2 took over the task).
I would like to skip those first runs and just have node #2 run the task every second.
But apparently, those first executions are not considered by Quartz to be "misfires": I tried all the possible "misfire instructions" but none of them could skip those runs.
Here is how the trigger is created:
public SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail) {
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
factoryBean.setStartDelay(0L);
factoryBean.setRepeatInterval(1000);
factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
// in case of misfire, ignore all missed triggers and continue :
factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
return factoryBean;
}
And here is the Quartz configuration:
org.quartz.scheduler.instanceName=quartz-clustered
org.quartz.scheduler.instanceId=AUTO
org.quartz.threadPool.threadCount=5
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval=5000
# A different classloader is needed to work with Spring Boot dev mode,
# see https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-known-restart-limitations
# and https://github.com/quartz-scheduler/quartz/issues/221
org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.ThreadContextClassLoadHelper
org.quartz.scheduler.skipUpdateCheck=true
spring-boot cluster-computing quartz-scheduler
add a comment |
I'm trying clustered Quartz in a sample Spring Boot 1.5 app.
But I'm very annoyed by the following behavior: when one node fails, the second node takes over the charge of running the task but runs all the executions that were missed.
Here's the full scenario (I have to nodes, strictly identical):
- Start node #1. Node #1 starts executing the task (which is a basic log) every second
- Start node #2. Node #2 does nothing yet.
- Stop node #1. For a few seconds, node #2 does nothing.
- When node #2 decides to begin the execution of the task, it begins with runs 4 or 5 executions of the task in one second.
- After that, the task gets executed every second as usual on node #2.
My guess is that the first executions of the task by node #2 (when I get 4 or 5 runs in only one second) is the run of the "missed" executions (those that would normally have been run between the time node #1 stopped and the time node #2 took over the task).
I would like to skip those first runs and just have node #2 run the task every second.
But apparently, those first executions are not considered by Quartz to be "misfires": I tried all the possible "misfire instructions" but none of them could skip those runs.
Here is how the trigger is created:
public SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail) {
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
factoryBean.setStartDelay(0L);
factoryBean.setRepeatInterval(1000);
factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
// in case of misfire, ignore all missed triggers and continue :
factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
return factoryBean;
}
And here is the Quartz configuration:
org.quartz.scheduler.instanceName=quartz-clustered
org.quartz.scheduler.instanceId=AUTO
org.quartz.threadPool.threadCount=5
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval=5000
# A different classloader is needed to work with Spring Boot dev mode,
# see https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-known-restart-limitations
# and https://github.com/quartz-scheduler/quartz/issues/221
org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.ThreadContextClassLoadHelper
org.quartz.scheduler.skipUpdateCheck=true
spring-boot cluster-computing quartz-scheduler
I'm trying clustered Quartz in a sample Spring Boot 1.5 app.
But I'm very annoyed by the following behavior: when one node fails, the second node takes over the charge of running the task but runs all the executions that were missed.
Here's the full scenario (I have to nodes, strictly identical):
- Start node #1. Node #1 starts executing the task (which is a basic log) every second
- Start node #2. Node #2 does nothing yet.
- Stop node #1. For a few seconds, node #2 does nothing.
- When node #2 decides to begin the execution of the task, it begins with runs 4 or 5 executions of the task in one second.
- After that, the task gets executed every second as usual on node #2.
My guess is that the first executions of the task by node #2 (when I get 4 or 5 runs in only one second) is the run of the "missed" executions (those that would normally have been run between the time node #1 stopped and the time node #2 took over the task).
I would like to skip those first runs and just have node #2 run the task every second.
But apparently, those first executions are not considered by Quartz to be "misfires": I tried all the possible "misfire instructions" but none of them could skip those runs.
Here is how the trigger is created:
public SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail) {
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
factoryBean.setStartDelay(0L);
factoryBean.setRepeatInterval(1000);
factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
// in case of misfire, ignore all missed triggers and continue :
factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
return factoryBean;
}
And here is the Quartz configuration:
org.quartz.scheduler.instanceName=quartz-clustered
org.quartz.scheduler.instanceId=AUTO
org.quartz.threadPool.threadCount=5
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval=5000
# A different classloader is needed to work with Spring Boot dev mode,
# see https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-known-restart-limitations
# and https://github.com/quartz-scheduler/quartz/issues/221
org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.ThreadContextClassLoadHelper
org.quartz.scheduler.skipUpdateCheck=true
spring-boot cluster-computing quartz-scheduler
spring-boot cluster-computing quartz-scheduler
asked Nov 22 '18 at 9:53
Cyril CCyril C
11
11
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53428200%2fquartz-failover-in-cluster%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53428200%2fquartz-failover-in-cluster%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown