java,quartz和在特定时间触发的多个任务保存在数据库中

时间:2016-09-14 18:52:50

标签: java quartz-scheduler

我正在构建一个系统,用户可以在日历中设置未来日期(小时和分钟)。在那个日期,触发器正在调用某个任务,对每个用户都是唯一的。

每个用户都可以设置不同的日期。系统从一开始就有10k +,用户可以创建多个触发器。

假设我有10k用户,每个用户平均创建3个触发器=>具有30k不同日期的30k触发器。

所有日期都保存在数据库中。

我是石英新手,能否以更优化的方式完成?

我正在考虑每分钟运行一次任务,这将导致将在下一个小时内运行并将其从数据库中删除的任务。

你有更好的想法吗?是否有人使用石英作为大量触发器。

3 个答案:

答案 0 :(得分:6)

您在数据库中备份了计划。如果我理解这个想法 - 你希望石英加载所有即将到来的任务,以便将来执行它们。

这是一个有问题的方法:

  1. 同步问题:我假设用户可以编辑,删除新任务并向数据库添加新任务。您必须定期要求数据库刷新石英作业的状态,删除一些作业,编辑其他作业等。这可能不是一件容易的事。程序的状态将是一个需要经常同步的长生存缓存。

  2. 性能和可扩展性问题:即使提议的解决方案可能适用于30K任务,可能也不适合70k或700k任务。在你的方法中,它不容易扩展 - 添加新机器需要额外的同步层 - 哪台机器应该实际执行哪个工作(因为它们都具有所有任务)。

  3. 我会建议:

    • 添加"阶段"到任务表(新的,排队的,运行的,完成的,失败的)
    • 将您的解决方案划分为多个组件。 (最初它们可以在一台机器上运行,但它很容易扩展)

    组件:

    • 任务查找器:定期执行(每隔几秒钟执行一次)。扫描数据库以查找" new"和due 很快的任务。将找到的任务发送到Message Queue,并将任务标记为"排队"在数据库中。标记为"排队"必须要小心,因为可能有多个任务查找器"。 (作为补充,它可能会发现任务已标记为"排队"或"运行"超过N分钟前且未完成"已完成"也未&# 34;取消" - 可能需要重新运行这些)

    • 消息队列 Taks Finder 任务执行者之间的连接器。

    • 任务执行者:侦听消息队列并处理收到的任务。将任务标记为"运行"最初和"完成"或者"失败"稍后。

    通过这种方法,您可以:

    • 多台计算机上的多个任务执行程序
    • 多台计算机上的多个任务计划程序
    • 即使其中一个任务计划程序或执行程序失败,它也不会是单点故障。有些任务会被延迟,但之后会被接收并运行。

    这可能无法解决所有情况,但可能是一个很好的起点。

答案 1 :(得分:2)

我不明白为什么你在这里需要石英。据我所知,quartz最适合用于安排后端内部进程,而不是用于从db获得的用户定义任务。

只需在创建触发器时处理触发器,根据触发器使用tasks将行保存到start_date表中,然后每隔一秒用start_date<选择所有未完成的任务。 SYSDATE。如果作业正在重复,则计算下一个执行时间并相应地插入新任务行/更新。

答案 2 :(得分:1)

正如Sam指出的那样,有一些很好的主题可以解决同样的问题:

在如上所述的系统中,处理此数量的触发器主要不是问题。但根据我的经验,这是一种更好的方式来创建类似于" JobChecker"。如果您允许用户创建自己的触发器,在某些情况下它可能真的会破坏Quartz。例如,如果5000用户在同一时间创建事件,Quartz将很难正确处理它们。 (这种情况不太可能经常发生,但是有可能因为你的规范不排除它。)Quartz只有在同时触发大量触发器时才会遇到困难。

我对此问题的建议是创建一个每小时/每分钟运行的作业,并且应该处理每个用户设置的事件。这种方式与cron中的bash作业相似。通过这种处理,即使"触发"的数量,您的系统也将非常稳定。急剧增加。基本上,如果您为了可扩展性而茁壮成长,那么您的思路就是正确的。