石英& Spring - 集群但不持久?

发布于 2024-09-10 11:43:09 字数 2126 浏览 8 评论 0原文

在我的 Spring 应用程序中,我使用 SchedulerFactoryBean 与 Quartz 集成。我们将拥有集群式 Tomcat 实例,因此我希望拥有集群式 Quartz 环境,以便相同的作业不会同时在不同的 Web 服务器上运行。

为此,我的 app-context.xml 如下:

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="cronTrigger"/>
            <ref bean="simpleTrigger" />
        </list>
    </property>
    <property name="dataSource" ref="dataSource"/>
    <property name="overwriteExistingJobs" value="true"/>
    <!-- found in applicationContext-data.xml -->
    <property name="applicationContextSchedulerContextKey" value="applicationContext"/>
    <property name="quartzProperties">
        <props>
            <prop key="org.quartz.scheduler.instanceName">SomeBatchScheduler</prop>
            <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
            <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
            <!--<prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop>-->
            <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
            <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
            <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
            <prop key="org.quartz.jobStore.isClustered">true</prop>
            <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
            <prop key="org.quartz.threadPool.threadCount">25</prop>
            <prop key="org.quartz.threadPool.threadPriority">5</prop>
        </props>
    </property>
</bean>

一切正常,除了当我尝试删除或更改触发器,然后重新启动我的应用程序时,旧触发器仍然保留在DB,并且仍然运行。我不想要这个,我只是希望它们在应用程序停止(或重新启动)时被删除。我将 overwriteExistingJobs 属性的值设置为 true,因为我认为这就是它的作用。

有什么想法吗?我只想将数据库用于集群,而不是除此之外的任何形式的持久性。

In my Spring application I'm using the SchedulerFactoryBean to integrate with Quartz. We're going to have clustered Tomcat instances, and thus I want to have a clustered Quartz environment, so that the same jobs don't run at the same time on different web servers.

To do this, my app-context.xml is as follows:

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="cronTrigger"/>
            <ref bean="simpleTrigger" />
        </list>
    </property>
    <property name="dataSource" ref="dataSource"/>
    <property name="overwriteExistingJobs" value="true"/>
    <!-- found in applicationContext-data.xml -->
    <property name="applicationContextSchedulerContextKey" value="applicationContext"/>
    <property name="quartzProperties">
        <props>
            <prop key="org.quartz.scheduler.instanceName">SomeBatchScheduler</prop>
            <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
            <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
            <!--<prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop>-->
            <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
            <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
            <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
            <prop key="org.quartz.jobStore.isClustered">true</prop>
            <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
            <prop key="org.quartz.threadPool.threadCount">25</prop>
            <prop key="org.quartz.threadPool.threadPriority">5</prop>
        </props>
    </property>
</bean>

Everything works well, except that when I attempt to remove or change a trigger, then restart my app, the old triggers are still persisted in the DB, and still run. I don't want this, I just want them to be deleted when the app stops (or is restarted). I set the value of the overwriteExistingJobs property to be true, since I thought that's what it did.

Any ideas? All I want to use the DB for is clustering, not any sort of persistence beyond that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云淡月浅 2024-09-17 11:43:09

我已经对这个主题进行了研究,这是 Quartz 中的一个众所周知的错误,我在他们的论坛上发现了一些帖子。为了解决这个问题,我创建了一个 bean 来删除 Quartz 表中的所有记录。你可以在你的 Quartz bean 加载之前调用这个 bean(在你的 Scheduler bean 上添加一个“depends-on”),当你的 spring 上下文被销毁时(确保数据库连接池仍然打开),或者通过某种形式手动调用用户界面。工作组也存在错误,请不要感到惊讶。我的第一个修复是创建一个带有该修复的客户 Quartz jar,但每当他们发布新版本时,升级就变得非常困难(我当时使用的是 1.4 或 1.5 - 不太记得了)。

I have done research on the topic and that's a well-known bug in Quartz, I found a few posts on their forum. To solve this problem I created a bean that deletes all the records in the Quartz table. You can call this bean before your Quartz bean is loaded (add a "depends-on" on your Scheduler bean), when your spring context is being destroyed (make sure the DB connection pool is still opened), or manually through some form of UI. There's also a bug on job groups, don't be surprised. My first fix was to create a customer Quartz jar with the fix but it got pretty hard to upgrade whenever they released a new version (I was using 1.4 or 1.5 at the time - don't really remember).

星軌x 2024-09-17 11:43:09

我在 clusteredquartz 2 上遇到了类似的问题。我没有运行camel,但这是同样的问题。

1)我没有见过通过简单地从 spring 上下文 xml 中删除作业/触发器来删除集群环境中的作业。

2) 由于数据库存储作业/触发器信息,因此如果您要添加或修改作业,跨服务器的滚动部署就会出现问题。服务器可以在将作业实现部署到应用程序服务器之前开始运行作业,除非您在部署更改之前关闭所有服务器。

为了解决这个问题,我想出了一个非常简单的解决方案。作为构建过程的一部分,我们已经在构建工件中捕获并存储了唯一的构建版本+编号(使用 gradle 变量替换)。为了解决这个问题,我们简单地让调度程序的名称包含唯一的构建版本+编号。这会导致最新的一组作业+触发器以新调度程序的名称添加到数据库中,并且一旦滚动部署完成,所有服务器都将使用新名称运行。这样就解决了删除问题,也解决了滚动部署问题。如果所有额外的调度程序名称都成为数据库中的问题,则可以根据需要编写一些内容来清理它们。

I ran into a similar problem with clustered quartz 2. I wasn't running camel, but it's the same problem.

1) There's no way I've seen to delete the jobs in a clustered environment by simply removing the jobs/triggers from the spring context xml.

2) Because the database stores the job/trigger information, rolling deployments across servers become problematic if you're adding or modifying jobs. Servers can start running jobs before the job implementation can be deployed to the app server, unless you take down all servers prior to deploying your changes.

To solve this, I came up with a pretty simple solution. As part of our build process, we were already capturing and storing a unique build version + number w/in the build artifact (using gradle variable substitution). To solve this problem, we simply made the scheduler's name include the unique build version+number. This results in the latest set of jobs+triggers being added to the db under the new scheduler's name, and once the rolling deploy is done, all servers are running w/ the new name. This solves the delete problem and also solves the rolling deployment problem. If all of the extra scheduler names becomes an issue in the db, something could be written to clean them up if needed.

你好,陌生人 2024-09-17 11:43:09

这是一篇旧文章,但为了那些需要解决方案的人的利益,就在这里。为属性“overwriteExistingJobs”指定“true”。您必须重新启动服务器,每次重新启动时,旧作业都将被删除。我不知道这在旧版本的quartz-scheduler中是否可行,我使用的是2.1.7

This is an old post, but for the benefit of those who need a solution, here it is. Specify "true" for the property "overwriteExistingJobs". You will have to restart your server and every time you restart, the old jobs will be removed. I do not know if this was possible in older versions of quartz-scheduler, I am using 2.1.7

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文