如何在用户的应用程序中定义作业的频率?

时间:2011-08-10 16:09:57

标签: cron playframework job-scheduling

我有一个必须重复启动工作的应用程序。但是(是的,如果没有,那本来就很容易......)我希望用户在应用程序中定义他们的备份频率。

最坏情况中,他们必须选择:

  • 每周,
  • 每日,
  • 每12个小时,
  • 每6小时一次,
  • 每小时

最佳案例中,他们应该能够使用crontab表达式(例如,请参阅documentation

怎么做?我是否每隔几分钟启动一项工作,检查上次执行时间,频率,然后在需要时启动另一项工作?我是否创建了一个由masterjob执行的队列?

欢迎任何线索,想法,意见,最佳实践,经验!

编辑:使用Akka调度程序解决了这个问题。好的,这是一个技术解决方案而不是设计答案,但仍然一切都很好。

每个用户定义的重复是一个actor,它将每个句点的消息发送给新的actor以执行实际的作业。

3 个答案:

答案 0 :(得分:1)

谷歌小组讨论过这个问题。据我所知,您必须定义一个每6小时启动一次的作业,并检查必须完成哪些备份。因此,您必须记住上次备份作业何时完成并自行进行控制。我不确定Quartz能否处理这样的要求。

我查看了源代码(总是一个很好的来源;-))并且每次都找到了一个方法,我认为这应该是你想做的。我怎么不确定这是否是一个聪明的设计,因为如果你有1000个用户,你将有1000个工作。我不确定Play是否能够处理如此大量的工作。

[更新]对于cron表达式,您应该查看JobPlugin.scheduleForCRON()

答案 1 :(得分:1)

根据您的要求/架构,可能有两种方法:

如果您只能使用Play:

  • 用户创建作业及其将运行的频率(crontab,无论如何)。
  • 在保存作业时,您将计算第一次必须运行的作业。然后,您可以向表JOBS添加一个条目,其中包含执行时间,作业ID和所需的任何其他信息。这是必需的,因为Play是无状态的,并且信息必须存储在DB中以供以后检索。
  • 您有一个作业在表中查询执行日期小于现在的条目。检索第一个,运行它,将其从表中删除,并为下一次执行添加一个新条目。您应该保留一些执行计数器,以便在任务失败时(这意味着该条目不会从DB中删除),它不会阻止作业一次又一次地尝试执行其他任务。
  • 此作业的频率设置为每秒运行一次。这样,虽然表中有信息,但您应该根据需要随时执行请求。如果你有足够的任务,Play不会产生一个新工作,而当前的工作正在工作,这个工作将为所有工作服务。如果没有,它将在某个时刻被杀死并在需要时恢复。

当然,用户的crons不会太精确,因为你必须考虑你自己的cron延迟加上队列中所有任务的执行延迟,这将按顺序运行。不是最好的方法,除非你以某种方式禁止每隔一分钟或更多时间运行的crons(为了安全)。如果他们超过一定的时间,检查一下crons的执行时间来杀死他们将是一个好主意。

如果您使用的不仅仅是Play:

我认为更好的选择是使用Quartz(参见this)在用户创建作业时创建将来的执行,并在执行结束后重新编写它。

答案 2 :(得分:0)

有几种方法可以解决这个问题。

如果你没有大量的工作,我只是坚持使用所需的灵活性。然后每小时(或您支持的最低间隔)检查所有这些并运行符合条件的那些。简单。

或者,如果您仍然希望使用cron语法,只需使用包装器将(导出)作业写入用户crontab,该包装器将回调您正在运行的应用程序,或者如果可能,则在独立进程中启动作业。