`

Quartz集群问题分析与排查

阅读更多

1、问题

         客户对分布式任务进行压力测试,发现分配任务时会有重复分派的情况。

2、分析

         1、客户应用基于我们的框架开发,分布式任务采用框架集成的Quartz进行任务调度,客户应用测试环境采用多台服务器集群部署,因此要求Quartz按照集群方式部署,否则多个服务器下的Quartz Job会有抢单的问题发生,所以,首先要验证Quartz集群配置是否正确有效;

         2、检查Job任务,看Job内部是否有抢单的情况,经分析发现AbstractQuartzService当前实现的Job接口,这就存在一个潜在的风险,当本次被调度的Job没有执行完,下次又启动了该Job时,会有任务竞争的情况;

         3、客户应用基于我们的开发框架,分布式任务的启动是通过quartz插件启动的,测试时需要模拟生产环境的启动过程进行测试。

3、验证Quartz集群过程

     3.1Quartz配置

3.1.1 quartz_client.properties

#============================================================================

# Configure Main Scheduler Properties 

#============================================================================

 

org.quartz.scheduler.instanceName = LmsScheduler

org.quartz.scheduler.instanceId = AUTO

 

#============================================================================

# Configure ThreadPool 

#============================================================================

 

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadCount = 3

org.quartz.threadPool.threadPriority = 5

 

#============================================================================

# Configure JobStore 

#============================================================================

 

org.quartz.jobStore.misfireThreshold = 60000

 

# org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

 

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate

org.quartz.jobStore.useProperties = false

org.quartz.jobStore.dataSource = myDS

org.quartz.jobStore.tablePrefix = SYS_TA_

org.quartz.jobStore.isClustered = true

 

#============================================================================

# Configure Datasources 

#============================================================================

 

org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver

org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@localhost:1521:orcl

org.quartz.dataSource.myDS.user = test

org.quartz.dataSource.myDS.password = test

org.quartz.dataSource.myDS.maxConnections = 5

 

#============================================================================

# Configure Plugins

#============================================================================

 

org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin

org.quartz.plugin.jobInitializer.fileNames = conf/schedule/quartz_jobs.xml

org.quartz.plugin.jobInitializer.overWriteExistingJobs = true

org.quartz.plugin.jobInitializer.failOnFileNotFound = true

org.quartz.plugin.jobInitializer.scanInterval = 0

org.quartz.plugin.jobInitializer.wrapInUserTransaction = false

 

说明:

1、注意标红的内容;

2quartz集群配置,要求集群的配置放在共享的数据库中,示例是采用oraclequartz对应的数据库配置表需要提前创建好;

3、由于框架集成的quartz-1.6.4版本,下面的配置没有对应实现类,测试时升级为quartz-1.7.1版本

org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate

 

3.1.2 quartz_jobs

<?xml version='1.0' encoding='utf-8'?>

<quartz xmlns="http://www.opensymphony.com/quartz/JobSchedulingData"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://www.opensymphony.com/quartz/JobSchedulingData

        http://www.opensymphony.com/quartz/xml/job_scheduling_data_1_5.xsd"

        version="1.5">

    <job>

        <job-detail>

            <name>simpleJob</name>

            <group>simpleJob</group>

            <description>test_dispatcher</description>

            <job-class>com.itown.dtask.service.SimpleQuartJob</job-class>

            <volatility>false</volatility>

            <durability>false</durability>

            <recover>false</recover>

        </job-detail>

        <trigger>

            <simple>

                <name>simpleJob</name>

                <group>simpleJob</group>

                <job-name>simpleJob</job-name>

                <job-group>simpleJob</job-group>

                <repeat-count>-1</repeat-count>

                <repeat-interval>10000</repeat-interval>

            </simple>

        </trigger>

    </job>

  

</quartz>

 

     3.2、编写测试类

3.2.1 Job实现类

public class SimpleQuartJob implements StatefulJob{

 

    public void execute(JobExecutionContext jec) throws JobExecutionException {

        System.out.println("SimpleQuartJob is running when " + new Date());

        try {

            Thread.sleep(15000);

        } catch (InterruptedException ex) {

            System.out.println(ex.getMessage());

        }       

    }

   

}

 

说明:该类实现了 StatefulJob接口。

 

3.2.2 QuartzPluginStarter

public class QuartzPluginStarter {

    private static Scheduler scheduler = null;

    private static final Logger logger = Logger.getLogger(QuartzPlugin.class.getName());

 

    public static void main(String[] args){

        try {

            // 从配置文件的路径中读取

            String fileName = "quartz_client.properties";

            File file = new File(RunModeManager.getInstance().getWorkPath(), "conf" + File.separator + "schedule" + File.separator + fileName);

            logger.info("加载配置文件, file=" + file.toString());

            if (!file.exists()) {

                logger.warning(String.format("调度程序配置文件[%s]不存在。", file));

                return;

            }

            SchedulerFactory sf = new StdSchedulerFactory(file.getAbsolutePath());

 

            scheduler = sf.getScheduler();

 

            scheduler.start();

           

            logger.info("SchedulerFactory started");

        } catch (SchedulerException ex) {

            logger.log(Level.SEVERE, null, ex);

        }

    }

}

 

说明:该类模拟了QuartzPlugin的实现,与生产环境启动quartz的机制相同。

     3.3、集群测试

1、启动一个QuartzPluginStarterA),观察Job的执行,正常时每次执行打印一条记录;

2、再启动一个QuartzPluginStarterB),模拟集群环境下启动多个Quartz,同时观察AB两个程序的执行情况,集群配置正确后,正常的结果是A或者B只有一个在执行;

3、如果是B执行,A等待,此时停掉B,观察A是否开始执行,如果开始执行就验证了Quartz集群的高可用特性。

测试结论:验证结果符合预期,Quartz集群环境下,只有一个节点下的Quartz生效,当启用的Quartz出问题时,Quartz集群会启动其他的Quartz节点,实现高可用。

 

4、后续工作

         1、检查并确认客户应用Quartz配置是否正确;

         2、修改AbstractQuartzService实现的接口,由原来实现Job改为实现StatefulJob接口。

 

5、参考

 http://www.quartz-scheduler.org/

http://www.ibm.com/developerworks/cn/opensource/os-cn-quartz/index.html

分享到:
评论

相关推荐

    Quartz集群简单资料(未整理)

    7. **监控与日志**:为了保证集群的稳定运行,需要实时监控各个节点的状态,以及日志记录,以便于排查问题。 提供的"quartz_Cluster" Demo可能包含了一个简单的集群配置示例,通过运行和分析这个示例,你可以更深入...

    记一次Quartz重复调度(任务重复执行)的问题排查.zip

    计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,...

    quartz 调用两次任务

    Quartz 是一个开源的作业调度框架,...总结,解决 "quartz 调用两次任务" 的问题需要对 Quartz 的工作原理有深入理解,并对代码、数据库、服务器配置进行细致的排查。通过上述步骤,通常能够找到问题所在并进行修复。

    QUARTZ项目实练

    - **监控与日志**:可以集成监控工具,如Quartz Admin,以便实时查看任务状态,同时确保有良好的日志记录系统,便于问题排查。 在"quartz-mybatis"压缩包中,应包含QUARTZ的配置文件、Mybatis的Mapper接口和XML...

    Quartz(作业调度)

    同时,Quartz内置了日志框架,方便记录任务执行的日志,便于调试和问题排查。 总的来说,Quartz是一个功能强大的作业调度框架,它的灵活性和可扩展性使其成为企业级应用定时任务的首选。通过合理的配置和设计,我们...

    定时任务quartz jar包

    - `log4j-1.2.16.jar` 是Log4j的版本1.2.16,这是一个经典的Java日志框架,用于记录应用程序运行过程中的事件,便于调试和问题排查。Quartz在运行过程中会产生许多日志信息,通过Log4j可以方便地管理和控制这些信息...

    quartz-3.0.3.1_quartes_源码.zip

    这对于定制化需求、性能优化或者排查问题都极其有价值。例如,了解 `org.quartz.simpl.SimpleThreadPool` 如何管理线程池,或者 `org.quartz.jdbcjobstore.TablePrefixAware` 如何处理多租户环境下的数据隔离,都能...

    quartz source包

    "quartz source包" 提供了 Quartz 框架的源代码,这对于理解其内部工作机制、进行定制开发或排查问题非常有帮助。 Quartz 主要包含以下几个核心概念: 1. **Job**:Job 是 Quartz 的基础,代表一个需要执行的任务...

    quartz 1.8.3资源包

    - log4j-1.2.14.jar:这是一个经典且广泛使用的日志记录框架,提供多种级别的日志输出,如DEBUG、INFO、WARN、ERROR等,便于调试和问题排查。 - slf4j-api-1.5.10.jar 和 slf4j-log4j12-1.5.10.jar:Simple ...

    quartz系列(三)terracotta2.3.5详细安装教程

    同时,确保日志配置合理,便于排查问题。 - **容错与恢复**:了解Terracotta的故障转移机制,确保在节点故障时,任务能被其他节点接管。 - **性能优化**:根据系统负载调整Terracotta和Quartz的配置,例如调整线程池...

    基于Quartz.Net 的任务调度计划框架

    - 在分布式环境下,Quartz.NET支持多节点集群,当一个节点出现问题时,任务可以被其他节点接管。 - 调度器的集群同步策略保证了任务的一致性和可靠性。 7. **自定义扩展**: - 用户可以根据需求实现自己的插件,...

    Window调度服务Quartz + EF完美结合

    7. **异常处理与日志记录**: 为了确保任务的稳定运行,应处理可能出现的异常,并使用EF记录日志信息,以便于排查问题。 8. **部署为Windows服务**: 最后,将应用打包成Windows服务,以便在后台持续运行,不受用户...

    quartz-1.6.6 教程,代码

    7. **故障排查与优化** - 监控 Scheduler 状态,确保任务按预期执行。 - 调整并发执行策略,避免资源竞争。 - 使用 Job Store,如 JDBCJobStore,保证高可用性。 8. **扩展性** - Quartz 支持集群部署,允许多...

    Quartz学习笔记

    同时,Scheduler还支持集群环境,可以在多台服务器上实现任务的高可用性和负载均衡。 4. **配置与使用**: 配置Quartz通常涉及定义Job和Trigger的XML文件,以及初始化Scheduler的代码。XML文件中会声明JobDetail...

    quartz 定时任务开发需要jar包

    6. **配置日志**:在应用中集成log4j,通过配置文件控制日志输出,以便于调试和问题排查。 在实际项目中,可能还需要考虑任务的并发控制、异常处理、任务暂停与恢复、任务删除等操作。同时,由于log4j-1.2.14版本较...

    Spring Quatz 书-Quartz.Job.Scheduling.Framework.Building

    2. **Spring与Quartz的整合**:讲解如何利用Spring的依赖注入(DI)和面向切面编程(AOP)特性,简化Quartz的配置和作业管理。通过Spring的XML配置或Java配置,可以方便地将作业和触发器绑定,实现灵活的作业调度...

    Spring+Quartz定时调度

    3. **监控和日志**:设置监控机制,记录Job执行情况,便于问题排查。 综上所述,Spring+Quartz的组合为开发者提供了强大的定时任务调度能力,通过灵活的配置和API,可以应对各种复杂的定时任务需求。配合提供的文档...

    Quartz时间调度

    6. **故障排查**:常见问题和解决方案,帮助用户在遇到问题时快速定位和解决。 7. **持久化机制**:Quartz如何使用数据库或其他持久化机制来存储和恢复Job和Trigger的状态。 8. **集群配置**:如果Quartz在集群...

Global site tag (gtag.js) - Google Analytics