Quartz在集群环境中无法正常工作

时间:2018-11-08 07:52:47

标签: java quartz-scheduler quartz

我在集群环境中的Websphere 8.5.5上使用 quartz-2.2.3 ,在集群环境中,我有2个节点,每个节点上有3个JVMS。

我正在配置应用程序启动时的作业。

问题在于该作业在每个节点上都配置了一次,我希望它在两个节点上只能配置一次,而不在每个节点上配置一次。

我的配置如下:

quartzConfig.properties:

#============================================================================
# Configure Main Scheduler Properties  
#============================================================================

org.quartz.scheduler.instanceName = MyJobScheduler
org.quartz.scheduler.instanceId = AUTO
#org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer = true

#============================================================================
# Configure ThreadPool  
#============================================================================

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5

#============================================================================
# Configure JobStore  
#============================================================================

org.quartz.jobStore.misfireThreshold = 60000

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.MSSQLDelegate 
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_

org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000

#============================================================================
# Configure Datasources  
#============================================================================

org.quartz.dataSource.myDS.driver = com.microsoft.sqlserver.jdbc.SQLServerDriver
org.quartz.dataSource.myDS.URL = jdbc:sqlserver://mydbserver:51803;databaseName=quartz 
org.quartz.dataSource.myDS.user = quartz
org.quartz.dataSource.myDS.password = quartz
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 1

#============================================================================
# Configure Shutdown Plugin  
#============================================================================

org.quartz.threadPool.makeThreadsDaemons=true
org.quartz.scheduler.makeSchedulerThreadDaemon=true
org.quartz.scheduler.interruptJobsOnShutdown=true
org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true

ApplicationContextListener:

public class ApplicationContextListener implements ServletContextListener {

    private StdSchedulerFactory factoryMyAppJob;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        configureQuartzJobs(event.getServletContext());
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        try {
            factoryMyAppJob.getScheduler().shutdown(false);
        } catch (SchedulerException e) {
            AppLogger.log(e);
        }
    }

    private void configureQuartzJobs(ServletContext servletContext) {

        String currentTime = new SimpleDateFormat("dd_MM_yyyy_HH").format(new Date());
        String myAppGroup = "myAppGroup";
        String myAppJob = "myAppJob";


        try {



            JobDetail job = JobBuilder.newJob(myAppJob.class).withIdentity(myAppJob, myAppGroup).build();

            Trigger triggerMyApp = TriggerBuilder.newTrigger().withIdentity(myAppJob, myAppGroup)
                    .withSchedule(simpleSchedule()
                            .withIntervalInMinutes(3).repeatForever())
                    .build();

            Properties propsMyAppJob = new Properties();

            boolean production = ConfigurationUtils.isProductionEnvironment();

            if (production) {
                propsMyAppJob.load(this.getClass().getClassLoader().getResourceAsStream("quartzConfig.properties"));
                factoryMyAppJob = new StdSchedulerFactory(propsMyAppJob);
            } else {
                factoryMyAppJob = new StdSchedulerFactory();
            }
            Scheduler scheduler = factoryMyAppJob.getScheduler();

            if (scheduler.checkExists(job.getKey())) {
                scheduler.deleteJob(job.getKey());
            }

            scheduler.scheduleJob(job, triggerMyApp);

            scheduler.start();


        } catch (ObjectAlreadyExistsException oae) {

        } catch (Exception e) {
            AppLogger.log(e);
        }
    }

}

1 个答案:

答案 0 :(得分:1)

此行为可能有很多原因。 配置似乎正确。

Quartz Documentation提到以下内容:

  
    

永远不要在单独的计算机上运行集群,除非它们的时钟使用某种形式的定期运行的时间同步服务(守护程序)进行同步,该服务非常规律地运行(时钟之间的时间间隔必须在一秒钟之内)

  

还有一个:

  
    

永远不要启动(scheduler.start())一个非集群实例,而该实例与运行(start()ed)任何其他实例的数据库表集相同。您可能会遇到严重的数据损坏,并且肯定会遇到不稳定的行为。

  

IMO两者都是集群无法正常运行的有效原因。