简体   繁体   English

Apache Camel quartz2不应用更改的cron表达式

[英]Apache Camel quartz2 doesn't apply changed cron expression

I'm trying to use camel-quartz2 component in a cluster mode with JDBCJobStore. 我正在尝试使用JDBCJobStore在集群模式下使用camel-quartz2组件。

quartz.properties file: quartz.properties文件:

org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceName=JobCluster

org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.dataSource=dsQuartzTest

org.quartz.jobStore.isClustered=true

org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=5
org.quartz.dataSource.dsQuartzTest.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.dsQuartzTest.URL = jdbc:oracle:thin:pmuser@//10.13.13.10:1521/PDB1
org.quartz.dataSource.dsQuartzTest.user = pmuser
org.quartz.dataSource.dsQuartzTest.password = oracle
org.quartz.dataSource.dsQuartzTest.maxConnections = 10

camel-context.xml file: camel-context.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Configures the Camel Context-->

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/spring"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://camel.apache.org/schema/spring
       http://camel.apache.org/schema/spring/camel-spring.xsd">

    <bean id="quartz2" class="org.apache.camel.component.quartz2.QuartzComponent">
        <property name="propertiesFile" value="quartz.properties"/>
    </bean>

    <bean id="quartzBean" class="com.ubs.rbs.integration.QuartzBean"/>

    <camel:camelContext xmlns="http://camel.apache.org/schema/spring">

        <camel:route id="quartzRoute">
            <camel:from uri="quartz2://tictac?cron=0+0/5+*+1/1+*+?+*"/>
            <camel:setBody>
                <camel:simple>
                    ${header.triggerName} - ${header.fireTime}
                </camel:simple>
            </camel:setBody>
            <camel:to uri="log:hello"/>
        </camel:route>

<!--
        <camel:route>
            <camel:from uri="timer://updateQuartzRoute?repeatCount=1"/>
            <camel:to uri="bean:quartzBean?method=reschedule(*,'quartzRoute')"/>
        </camel:route>
-->

    </camel:camelContext>

</beans>

When I first start the application, camel-quartz2 component schedules job with appropriate cron expression, and all works just OK. 当我第一次启动应用程序时,camel-quartz2组件使用适当的cron表达式调度作业,并且一切正常。 But, when I stop all instances of app, trigger remains in a WAITING state (it's, probably, OK for cluster, as component cannot tell when last instance is stopped, also, I cannot tell if this point is relevant, but without cluster it seems was no issue). 但是,当我停止应用程序的所有实例时,触发器仍然处于WAITING状态(对于集群来说可能是好的,因为组件无法判断最后一个实例何时停止,同样,我无法判断这一点是否相关,但没有集群它似乎没有问题)。 So, when I start app next time trigger is already exists and its settings won't apply. 因此,当我下次启动应用程序时,触发器已经存在且其设置将不适用。 Importantly, when I change cron expression and restart all instances, quartz uses old expression from DB, not new one from component's uri. 重要的是,当我更改cron表达式并重新启动所有实例时,quartz使用DB中的旧表达式,而不是组件的uri中的新表达式。

I found a workaround for this issue, using additional route (commented out in the xml above) to reschedule quartz in the custom bean as below: 我找到了解决此问题的方法,使用其他路由(在上面的xml中注释掉)来重新调度自定义bean中的quartz,如下所示:

public class QuartzBean {

    public void reschedule(CamelContext context, String quartzRouteId) throws Exception {
        QuartzEndpoint endpoint = (QuartzEndpoint) context.getRoute(quartzRouteId).getEndpoint();
        QuartzComponent component = endpoint.getComponent();
        Scheduler scheduler = component.getScheduler();

        Trigger oldTrigger = scheduler.getTrigger(endpoint.getTriggerKey());
        TriggerBuilder tb = oldTrigger.getTriggerBuilder();

        Trigger newTrigger = tb.withSchedule(CronScheduleBuilder.cronSchedule(endpoint.getCron())).build();

        scheduler.rescheduleJob(oldTrigger.getKey(), newTrigger);
    }
}

Alternatively, I can patch camel-quartz2 component as below (org.apache.camel.component.quartz2.QuartzEndpoint#addJobInScheduler): 或者,我可以修改camel-quartz2组件,如下所示(org.apache.camel.component.quartz2.QuartzEndpoint #addJobInScheduler):

private void addJobInScheduler() throws Exception {
    // Add or use existing trigger to/from scheduler
    Scheduler scheduler = getComponent().getScheduler();
    JobDetail jobDetail;
    boolean triggerExisted = scheduler.getTrigger(triggerKey) != null;
    if (triggerExisted) {
        ensureNoDupTriggerKey();
    }

    jobDetail = createJobDetail();
    Trigger trigger = createTrigger(jobDetail);

    updateJobDataMap(jobDetail);

    // Schedule it now. Remember that scheduler might not be started it, but we can schedule now.
    Date nextFireDate = triggerExisted ? scheduler.rescheduleJob(triggerKey, trigger) : scheduler.scheduleJob(jobDetail, trigger);
    if (LOG.isInfoEnabled()) {
        LOG.info("Job {} (triggerType={}, jobClass={}) is scheduled. Next fire date is {}",
                 new Object[] {trigger.getKey(), trigger.getClass().getSimpleName(),
                               jobDetail.getJobClass().getSimpleName(), nextFireDate});
    }

    // Increase camel job count for this endpoint
    AtomicInteger number = (AtomicInteger) scheduler.getContext().get(QuartzConstants.QUARTZ_CAMEL_JOBS_COUNT);
    if (number != null) {
        number.incrementAndGet();
    }

    jobAdded.set(true);
}

Unlike the current version in the project's repository, my version always creates new trigger and reschedules job if trigger already existed. 与项目存储库中的当前版本不同,如果触发器已经存在,我的版本总是创建新的触发器和重新安排作业。

My questions are: Am I missing something obvious? 我的问题是:我错过了一些明显的东西吗? How this component supposed to work in such scenario? 这个组件应该如何在这种情况下工作? Should I try to change component itself or is there a better way to change its schedule from outside? 我应该尝试更改组件本身还是有更好的方法从外部更改其计划?

UPD: I tried versions 2.13.1 from maven and 2.14.SNAPSHOT from sources. UPD:我从maven尝试了2.13.1版本,从源代码尝试了2.14.SNAPSHOT。

Camel versions 2.12.2 and before have known bugs related to Quartz. Camel版本2.12.2和之前已知与Quartz相关的错误。 Give 2.12.3 and upwards a try, if you're not. 如果不是,请试试2.12.3及以上。

我提交了一个错误: https//issues.apache.org/jira/browse/CAMEL-7627以及补丁和单元测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM