Spring 4 Quartz 2 Weblogic 12c Oracle 12c-偶尔会在集群中的两个节点上触发作业
我们使用Spring4.2.8、Quartz 2.2.3、WebLogic12c作为应用服务器,Oracle12c作为RDBMS。我们有一个集群环境,其中有两个节点是weblogic集群的一部分。我们看到,偶尔会在集群中的两个节点上触发quartz作业 弹簧石英配置如下所示。如果有任何配置需要调整以防止作业同时从两台服务器启动,请提供建议-Spring 4 Quartz 2 Weblogic 12c Oracle 12c-偶尔会在集群中的两个节点上触发作业,spring,oracle,quartz-scheduler,weblogic12c,Spring,Oracle,Quartz Scheduler,Weblogic12c,我们使用Spring4.2.8、Quartz 2.2.3、WebLogic12c作为应用服务器,Oracle12c作为RDBMS。我们有一个集群环境,其中有两个节点是weblogic集群的一部分。我们看到,偶尔会在集群中的两个节点上触发quartz作业 弹簧石英配置如下所示。如果有任何配置需要调整以防止作业同时从两台服务器启动,请提供建议- <beans:bean id="sendJobId" class="org.springframework.schedulin
<beans:bean id="sendJobId"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<beans:property name="jobClass" value="GenericSchedulerJob" />
<beans:property name="jobDataAsMap">
<beans:map>
<beans:entry key="batchProcessorName" value="sendJob" />
</beans:map>
</beans:property>
</beans:bean>
<beans:bean id="sendJobTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<beans:property name="jobDetail" ref="sendJobId" />
<beans:property name="cronExpression" value="0 0 9 * * ? *" />
<beans:property name="misfireInstructionName" value="MISFIRE_INSTRUCTION_DO_NOTHING" />
</beans:bean>
<beans:bean id="schedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<beans:property name="autoStartup" value="true" />
<beans:property name="applicationContextSchedulerContextKey"
value="applicationContext" />
<beans:property name="dataSource" ref="testDB" />
<beans:property name="waitForJobsToCompleteOnShutdown"
value="true" />
<beans:property name="quartzProperties">
<beans:props>
<beans:prop
key="org.quartz.scheduler.skipUpdateCheck">true</beans:prop>
<beans:prop key="org.quartz.scheduler.instanceName">EFF-Scheduler</beans:prop>
<beans:prop key="org.quartz.scheduler.instanceId">AUTO</beans:prop>
<beans:prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool
</beans:prop>
<beans:prop key="org.quartz.threadPool.threadCount">20</beans:prop>
<beans:prop key="org.quartz.threadPool.threadPriority">5</beans:prop>
<beans:prop key="org.quartz.jobStore.misfireThreshold">60000</beans:prop>
<beans:prop key="org.quartz.jobStore.tablePrefix">QRTZ_</beans:prop>
<beans:prop key="org.quartz.jobStore.isClustered">true</beans:prop>
<beans:prop key="org.quartz.jobStore.clusterCheckinInterval">20000</beans:prop>
<beans:prop key="org.quartz.jobStore.selectWithLockSQL">SELECT * FROM {0}LOCKS UPDLOCK WHERE
LOCK_NAME = ?
</beans:prop>
<beans:prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate
</beans:prop>
</beans:props>
</beans:property>
<beans:property name="triggers">
<beans:list>
<beans:ref bean="sendJobTrigger" />
</beans:list>
</beans:property>
以下是QRTZ_锁表中的条目-
schedulerFactoryBean TRIGGER_ACCESS
schedulerFactoryBean STATE_ACCESS
GenericSchedulerJob.java的内容如下所示-
@Component
public class GenericSchedulerJob extends QuartzJobBean {
private String batchProcessorName;
private static final Logger LOG = LoggerFactory.getLogger(GenericSchedulerJob.class);
@Override
protected void executeInternal(JobExecutionContext jobContext) throws JobExecutionException {
ApplicationContext context;
try {
context = (ApplicationContext) jobContext.getScheduler().getContext().get("applicationContext");
BaseSchedulerJob job = (BaseSchedulerJob) context.getBean(batchProcessorName);
job.execute(Integer.toHexString(hashCode()));
} catch (SchedulerException e) {
LOG.error("ERROR :" + e.getMessage(), e);
}
}
public String getBatchProcessorName() {
return batchProcessorName;
}
public void setBatchProcessorName(String batchProcessorName) {
this.batchProcessorName = batchProcessorName;
}
}
@Component
public class SendJob implements BaseSchedulerJob{
@Autowired
private SendService sendService;
public void execute(String processId) {
sendService.sendPendingPickRequests(job);
}
}
实际的quartz作业是从DB中获取数据,用从DB中检索到的数据创建一个excel文件,并通过电子邮件将其发送给收件人
根据日志显示,当一台服务器上的作业正在将数据写入excel文件时,另一台服务器上的作业正在启动。Ledniv的可能副本@DisallowConcurrentExecution或有状态作业是否在群集环境中工作,或仅在同一节点上工作?我还没有在群集上测试它,但是我想它应该会起作用的嗨,Jaccob,有用吗?
schedulerFactoryBean TRIGGER_ACCESS
schedulerFactoryBean STATE_ACCESS
@Component
public class GenericSchedulerJob extends QuartzJobBean {
private String batchProcessorName;
private static final Logger LOG = LoggerFactory.getLogger(GenericSchedulerJob.class);
@Override
protected void executeInternal(JobExecutionContext jobContext) throws JobExecutionException {
ApplicationContext context;
try {
context = (ApplicationContext) jobContext.getScheduler().getContext().get("applicationContext");
BaseSchedulerJob job = (BaseSchedulerJob) context.getBean(batchProcessorName);
job.execute(Integer.toHexString(hashCode()));
} catch (SchedulerException e) {
LOG.error("ERROR :" + e.getMessage(), e);
}
}
public String getBatchProcessorName() {
return batchProcessorName;
}
public void setBatchProcessorName(String batchProcessorName) {
this.batchProcessorName = batchProcessorName;
}
}
@Component
public class SendJob implements BaseSchedulerJob{
@Autowired
private SendService sendService;
public void execute(String processId) {
sendService.sendPendingPickRequests(job);
}
}