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

java、quartz和在特定时间触发的多个任务保存在数据库中,java,quartz-scheduler,Java,Quartz Scheduler,我正在构建一个系统,用户可以在日历中设置未来的日期(精确到小时和分钟)。在那个日期,触发器正在调用特定的任务,对于每个用户都是唯一的 每个用户都可以设置不同的日期。系统从一开始就有10k+的电压,用户可以创建多个触发器 所以假设我有10000个用户,每个用户平均创建3个触发器=>30k个触发器,每个触发器有30k个不同的日期 所有日期都保存在数据库中 我是石英的新手,这可以用一种更优化的方式来完成吗 我在考虑每分钟运行一个任务,这样可以得到下一个小时应该运行的任务,并将它们从数据库中删除 你有更

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

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

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

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

我是石英的新手,这可以用一种更优化的方式来完成吗

我在考虑每分钟运行一个任务,这样可以得到下一个小时应该运行的任务,并将它们从数据库中删除

你有更好的主意吗?是否有人将quartz用于大量触发器。

正如所指出的,有一些不错的主题解决了相同的问题:

在像上面提到的那样的系统中,处理这么多的触发器应该不是什么问题。但根据我的经验,这是一个更好的方法来创建一个像“工作检查”。如果您允许用户创建自己的触发器,在某些情况下,它可能真的会破坏Quartz。例如,如果5000名用户在同一时间创建事件,Quartz将很难正确处理它们。(这种情况不太可能经常发生,但这是可能的,因为您的规范没有排除它。)Quartz只有在同时触发大量触发器时才会遇到困难


我对这个问题的建议是创建一个每小时/分钟运行一次的作业,它应该处理每个用户设置的事件。这种方式类似于
bash
中的
cron
作业。通过这种处理,即使“触发器”的数量急剧增加,您的系统也将相当稳定。如果您在可扩展性方面表现出色,那么您的思路基本上是正确的。

我不明白您为什么需要石英。据我记忆所及,quartz最好用于调度后端内部流程,而不是从db获得的用户定义任务


只需在创建触发器时对其进行处理,根据触发器将一行保存到带有
开始日期的
任务
表中,并每隔一秒钟使用
开始日期
数据库中已备份计划。如果我理解这个想法-您希望quartz加载所有即将到来的任务,以便在将来执行它们

这是一种有问题的方法:

  • 同步问题:我假设用户可以编辑、删除和向数据库添加新任务。您必须定期要求数据库刷新quartz作业的状态、删除一些作业、编辑其他作业等。这可能不是一件小事。程序的状态将是一个长期存在的缓存,需要经常进行同步

  • 性能和可伸缩性问题:即使建议的解决方案可能适用于30K任务,也可能不适用于70k或700k任务。在您的方法中,扩展并不容易—添加新机器需要额外的同步层—哪台机器应该实际执行哪项作业(因为它们都有所有任务)

  • 我的建议是:

    • 将“阶段”添加到任务表(新建、排队、运行、完成、失败)
    • 将解决方案分为几个部分。(最初它们可以在一台机器上运行,但很容易扩展)
    组成部分:

    • 任务查找程序:定期执行(每隔几秒钟一次)。扫描数据库以查找“新”任务以及即将到期的任务。将找到的任务发送到消息队列,并在数据库中将该任务标记为“排队”。必须小心地标记为“排队”,因为可能有多个“任务查找器”。(作为补充,它可能会发现N分钟前标记为“排队”或“正在运行”且未“完成”或“取消”的任务-可能需要重新运行这些任务)

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

    • 任务执行器:侦听消息队列并处理它接收到的任务。将任务最初标记为“正在运行”,随后标记为“已完成”或“失败”

    通过这种方法,您可以:

    • 多台计算机上的多个任务执行器
    • 多台计算机上的多个任务调度器
    • 即使其中一个任务调度器或执行器失败,也不是单点故障。某些任务将被延迟,但随后将被提取并运行

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

    触发器的数量是一个问题,因为?您是否测试/测量过这是一个问题?看起来你正在试图解决一些你认为是问题的事情。让Quartz来处理,你可以做的是清理已完成的任务(或将它们移动到存档),但对于其余的任务,让Quartz来处理。我认为你应该看看这里的评论。