在集群环境中使用 Quartz 和 Mule

Posted

技术标签:

【中文标题】在集群环境中使用 Quartz 和 Mule【英文标题】:Using Quartz with Mule in Clustered Environment 【发布时间】:2015-08-21 03:13:59 【问题描述】:

我有一个场景,我正在尝试从 Yelp API 读取数据并希望在特定时间间隔后将其放入 ActiveMQ 队列中,因此我正在使用石英调度程序。我的石英调度程序每 10 分钟运行一次,并且将数据推送到队列中, 到这里为止一切都很好,

现在我希望它在集群环境中工作,我将部署 2 个实例并监听相同的 Yelp 端点,现在发生的情况是,我的 2 个实例的石英调度程序在同一个实例上执行,它们提取相同的信息来自 Yelp,导致相同的消息登陆 ActiveMQ 队列,即 DUPLICATES,(我想将集群环境用于高可用性目的,即如果任何节点发生故障,其他节点可以接管。)

那么在Mule中是否有任何配置可以将一个节点提升为主节点,将另一个节点提升为故障转移节点。

感谢大家的帮助!

【问题讨论】:

您是否在 Mule 企业版中使用集群? @DavidDossot 暂时没有,但是有没有办法做到这一点,使用企业版?,你能说明一下吗? 是的,EE 集群负责管理集群中的单例端点,例如轮询器。如果您不使用 EE,则必须构建一些自定义的东西才能这样做。 您可以使用 JDBC 兼容的数据库将 Quartz 分布在多个节点上。设置有些混乱,但您可以在多个 Mule CE 实例上进行单节点轮询。也就是说,EE 集群功能可能是最简单的方法。 【参考方案1】:

我们使用 3.5.2-企业版,但不确定社区版是否有限制。你可以试试下面的方法,看看是否有效:

<!-- Quart Connector with one thread to ensure that we don't have duplicate processing at any point of time -->
<quartz:connector name="QuartzConnector" validateConnections="true">
    <receiver-threading-profile maxThreadsActive="1" />
</quartz:connector> 

然后在您计划触发此操作的任何位置在您的流程中引用它。

<flow name="test">
    <quartz:inbound-endpoint jobName="myQuartzJob" cronExpression="$my.job.cron.expression" repeatInterval="$my.job.repeat.interval" responseTimeout="$my.job.response.timeout" connector-ref="QuartzConnector">
        <quartz:event-generator-job>
            <quartz:payload>blah</quartz:payload>
        </quartz:event-generator-job>
    </quartz:inbound-endpoint>
</flow>    

希望有效。

【讨论】:

@DavidDossot 这能正常工作吗?我有一点疑问,因为我将拥有多个 mule 实例,并且分析将导致每个实例有一个活动线程【参考方案2】:

这将由 cron 表达式 0/10 * * * * ?(每 10 秒)触发,用于运行同一应用程序并连接到同一数据库(在本例中为 mysql)的所有节点之一。 Quartz 设置有点乱。您需要配置数据库等,但我让您研究 Quartz 文档。您应该查看版本 1.8.x 而不是 2.x。

这几乎是 Mule EE 中集群端点的一种预算替代方案。当您不想集群您的 EE 节点或需要运行 CE 节点时,它很有用。

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:quartz="http://www.mulesoft.org/schema/mule/quartz" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.6.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/quartz http://www.mulesoft.org/schema/mule/quartz/current/mule-quartz.xsd">

    <quartz:connector name="quartzConnector" validateConnections="true" doc:name="Quartz">
        <quartz:factory-property key="org.quartz.scheduler.instanceName" value="QuartzScheduler" />
        <quartz:factory-property key="org.quartz.scheduler.instanceId" value="AUTO" />
        <quartz:factory-property key="org.quartz.jobStore.isClustered" value="true" />
        <quartz:factory-property key="org.quartz.scheduler.jobFactory.class" value="org.quartz.simpl.SimpleJobFactory" />
        <quartz:factory-property key="org.quartz.threadPool.class" value="org.quartz.simpl.SimpleThreadPool" />
        <quartz:factory-property key="org.quartz.threadPool.threadCount" value="3" />
        <quartz:factory-property key="org.quartz.scheduler.rmi.proxy" value="false" />
        <quartz:factory-property key="org.quartz.scheduler.rmi.export" value="false" />

        <quartz:factory-property key="org.quartz.jobStore.class" value="org.quartz.impl.jdbcjobstore.JobStoreTX" />
        <quartz:factory-property key="org.quartz.jobStore.driverDelegateClass" value="org.quartz.impl.jdbcjobstore.StdJDBCDelegate" />
        <quartz:factory-property key="org.quartz.jobStore.dataSource" value="quartzDataSource" />
        <quartz:factory-property key="org.quartz.jobStore.tablePrefix" value="QRTZ_" />

        <quartz:factory-property key="org.quartz.dataSource.quartzDataSource.driver"  value="com.mysql.jdbc.Driver" />

        <quartz:factory-property key="org.quartz.dataSource.quartzDataSource.URL" value="jdbc:mysql://localhost:3306/qrtz" />
        <quartz:factory-property key="org.quartz.dataSource.quartzDataSource.user" value="root" />
        <quartz:factory-property key="org.quartz.dataSource.quartzDataSource.password"  value="" />
        <quartz:factory-property key="org.quartz.dataSource.quartzDataSource.maxConnections"  value="8" /> 

    </quartz:connector>

    <flow name="cFlow1">
        <quartz:inbound-endpoint jobName="job1" cronExpression="0/10 * * * * ?" repeatInterval="0" connector-ref="quartzConnector" responseTimeout="10000" doc:name="Quartz">
            <quartz:event-generator-job>
                <quartz:payload>Job Trigger</quartz:payload>
            </quartz:event-generator-job>
        </quartz:inbound-endpoint>
        <logger level="INFO" message="Got message" doc:name="Logger"/>
    </flow>        
</mule>

【讨论】:

同意这是使用 Quartz 实现集群的一种方法,适用于 CE 和 Mule EE。但是 AFAIK Mule EE 还提供了一个社区版的quartz,所以 Quartz JDBCJobStore 可能是唯一的选择。除非 Mule 为 Gigaspaces 或 jgroups 提供了另一个集群选项。有人可以确认一下吗?

以上是关于在集群环境中使用 Quartz 和 Mule的主要内容,如果未能解决你的问题,请参考以下文章

Spring+Quartz集群环境下定时调度的解决方案

Spring整合Quartz定时任务 在集群分布式系统中的应用(Mysql数据库环境)

Springboot集成Quartz集群

spring boot 整合 quartz 集群环境 实现 动态定时任务配置原

quartz集群分布式(并发)部署解决方案-Spring

spring quartz定时任务集群环境下如何实现只在单个节点运行