【问题标题】:Play Framework/Akka scheduler delay driftPlay Framework/Akka 调度器延迟漂移
【发布时间】:2014-10-27 08:36:16
【问题描述】:

我有一个 Play 2.3 项目,我需要每小时安排一次动作,所以我使用 Akka 在 Global.onStart 中安排它。该操作肯定需要不到 1 小时才能完成(它会检查数据库是否有潜在更新,然后根据这些更新执行一些 Web 请求)。

但是,除了第一个动作之外,每次动作都会延迟 1 秒。所以在 60 小时/更新之后,它会延迟整整一分钟,大概在大约 9 个月后它会延迟整整一个小时。

一开始我尝试将频率设置为 (60 * 60) - 1 秒,一开始它可以工作,但有时它还是会偏移,最终它运行得太晚了。

似乎直到动作完成频率才开始倒计时(可以这么说),这导致了这种延迟,那么我该怎么做才能防止这种漂移?

这是我必须计算延迟和安排行动的代码:

// Time until next full hour
static public FiniteDuration getDelay()
{
    Calendar currentCalendar = Calendar.getInstance();

    long minute = currentCalendar.get(Calendar.MINUTE);
    long second = currentCalendar.get(Calendar.SECOND);
    long ms = currentCalendar.get(Calendar.MILLISECOND);

    minute = (60L - minute) * 60 * 1000;
    second = (60 - second) * 1000;
    ms = 1000L - ms;

    long delay = minute + second + ms;

    return FiniteDuration.create(delay, TimeUnit.MILLISECONDS);
}

// Update once every 60 minutes
static public FiniteDuration getFrequency()
{
    return FiniteDuration.create(60, TimeUnit.MINUTES);
}

Akka.system().scheduler()
    .schedule(getDelay(), getFrequency(),
    Publisher.makeRunnable(), Akka.system().dispatcher());

【问题讨论】:

  • 这个答案stackoverflow.com/questions/14145186/… 似乎是关于同样的问题声称这是一个已在 Akka 2.1 中修复的问题,但我使用的是 Play 2.3(不知道如何检查哪个我正在使用的 Akka 版本,但我相信它是更高版本的)并且这个问题仍然存在。
  • Play 2.3 使用 Akka 2.3,因此您应该提交错误或确保您的初始延迟计算正确。
  • 似乎最初的延迟不应该有太大的区别,即使在第一次行动之后频率应该仍然是,但它不是

标签: java playframework-2.0 akka playframework-2.3


【解决方案1】:

akka 调度程序并不声称其调度是准确的,因为它只是维护一个作业队列,它会在每个“tick”上检查它(请参阅this page 上的警告)。如果您想准确地安排工作时间,我建议您使用类似 cron 的库,例如 Quartz,以便您可以在正确的时间发出消息。这使您可以根据挂钟时间更精确地安排作业,而不是依赖 Akka 的“tick”概念。

【讨论】:

    【解决方案2】:

    您的延迟计算似乎没有考虑到最接近的整小时:

    比如说,当前时间是3:58:49.999,与4:00:00.000 的差异是 00:01:10.001。但是,运行您的代码将是00:02:11.001

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2015-12-29
      • 1970-01-01
      相关资源
      最近更新 更多