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

标签 java quartz-scheduler

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

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

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

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

我是 quartz 的新手,能否以更优化的方式完成此操作?

我正在考虑让任务每分钟运行一次,以获取假设在下一个小时运行的任务并将它们从数据库中删除。

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

最佳答案

您已将时间表备份在数据库中。如果我理解这个想法 - 您希望 quartz 加载所有即将到来的任务以在将来执行它们。

这是有问题的方法:

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

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

我的建议:

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

组件:

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

  • Message Queue:Taks FinderTask Executor 之间的连接器。

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

通过这种方法,您可以:

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

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

关于java, quartz 和特定时间触发的多个任务保存在数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39497667/

相关文章:

grails - Grails中每分钟的cron定义是什么?

java - org.hibernate.PropertyAccessException : IllegalArgumentException occurred calling getter of com. dms.model.Group.groupId

java 8 threadPoolExecutor 在 N 任务后卡住并返回语句

java - Android 应用程序在设备中安装后无法找到位置

java - 如何在 GWT 中使用 websocket

java - Camel quartz 2 : clustering configuration

Grails - Quartz 作业触发器中的参数

java - 在 Quartz 和 Apache Camel 中使用计时器

javaquartz cron计划错误

java - 如何删除 SOAPHeaderElement 的命名空间