java、quartz和在特定时间触发的多个任务保存在数据库中
我正在构建一个系统,用户可以在日历中设置未来的日期(精确到小时和分钟)。在那个日期,触发器正在调用特定的任务,对于每个用户都是唯一的 每个用户都可以设置不同的日期。系统从一开始就有10k+的电压,用户可以创建多个触发器 所以假设我有10000个用户,每个用户平均创建3个触发器=>30k个触发器,每个触发器有30k个不同的日期 所有日期都保存在数据库中 我是石英的新手,这可以用一种更优化的方式来完成吗 我在考虑每分钟运行一个任务,这样可以得到下一个小时应该运行的任务,并将它们从数据库中删除 你有更好的主意吗?是否有人将quartz用于大量触发器。正如所指出的,有一些不错的主题解决了相同的问题:java、quartz和在特定时间触发的多个任务保存在数据库中,java,quartz-scheduler,Java,Quartz Scheduler,我正在构建一个系统,用户可以在日历中设置未来的日期(精确到小时和分钟)。在那个日期,触发器正在调用特定的任务,对于每个用户都是唯一的 每个用户都可以设置不同的日期。系统从一开始就有10k+的电压,用户可以创建多个触发器 所以假设我有10000个用户,每个用户平均创建3个触发器=>30k个触发器,每个触发器有30k个不同的日期 所有日期都保存在数据库中 我是石英的新手,这可以用一种更优化的方式来完成吗 我在考虑每分钟运行一个任务,这样可以得到下一个小时应该运行的任务,并将它们从数据库中删除 你有更
我对这个问题的建议是创建一个每小时/分钟运行一次的作业,它应该处理每个用户设置的事件。这种方式类似于
bash
中的cron
作业。通过这种处理,即使“触发器”的数量急剧增加,您的系统也将相当稳定。如果您在可扩展性方面表现出色,那么您的思路基本上是正确的。我不明白您为什么需要石英。据我记忆所及,quartz最好用于调度后端内部流程,而不是从db获得的用户定义任务
只需在创建触发器时对其进行处理,根据触发器将一行保存到带有
开始日期的任务
表中,并每隔一秒钟使用开始日期
数据库中已备份计划。如果我理解这个想法-您希望quartz加载所有即将到来的任务,以便在将来执行它们
这是一种有问题的方法:
同步问题:我假设用户可以编辑、删除和向数据库添加新任务。您必须定期要求数据库刷新quartz作业的状态、删除一些作业、编辑其他作业等。这可能不是一件小事。程序的状态将是一个长期存在的缓存,需要经常进行同步
性能和可伸缩性问题:即使建议的解决方案可能适用于30K任务,也可能不适用于70k或700k任务。在您的方法中,扩展并不容易—添加新机器需要额外的同步层—哪台机器应该实际执行哪项作业(因为它们都有所有任务)
我的建议是:
- 将“阶段”添加到任务表(新建、排队、运行、完成、失败)
- 将解决方案分为几个部分。(最初它们可以在一台机器上运行,但很容易扩展)
组成部分:
- 任务查找程序:定期执行(每隔几秒钟一次)。扫描数据库以查找“新”任务以及即将到期的任务。将找到的任务发送到消息队列,并在数据库中将该任务标记为“排队”。必须小心地标记为“排队”,因为可能有多个“任务查找器”。(作为补充,它可能会发现N分钟前标记为“排队”或“正在运行”且未“完成”或“取消”的任务-可能需要重新运行这些任务)
- 消息队列:Taks Finder和任务执行器之间的连接器
- 任务执行器:侦听消息队列并处理它接收到的任务。将任务最初标记为“正在运行”,随后标记为“已完成”或“失败”
通过这种方法,您可以:
- 多台计算机上的多个任务执行器
- 多台计算机上的多个任务调度器
- 即使其中一个任务调度器或执行器失败,也不是单点故障。某些任务将被延迟,但随后将被提取并运行
这可能不能解决所有的情况,但将是一个很好的起点。触发器的数量是一个问题,因为?您是否测试/测量过这是一个问题?看起来你正在试图解决一些你认为是问题的事情。让Quartz来处理,你可以做的是清理已完成的任务(或将它们移动到存档),但对于其余的任务,让Quartz来处理。我认为你应该看看这里的评论。