在App Engine上将来某个远程执行任务的最有效方法是什么?

时间:2013-02-20 18:14:42

标签: java google-app-engine scheduled-tasks scheduling

我在App Engine上有一个消耗一些数据的应用程序。在解析了这些数据后,它会知道它需要在一段时间内执行某些事情 - 可能不会持续数小时或数周。

在App Engine上经过一段时间后执行一段代码的最佳方法是什么?

我认为使用来自TaskQueue的Countdown MillisEtaMillis会有效,但是没有看到任何人做同样事情的证据,特别是对于如此长的时间帧。

这是最好的方法,还是有更好的方法?

5 个答案:

答案 0 :(得分:2)

如果您能够在数据存储区中保留一个对象并包含所有相关信息以供将来处理(包括对象数据的处理应该开始时),那么您可以让cron作业定期查询具有日期的数据存储区/时间范围过滤并在适当的时间触发处理任何上述对象。

答案 1 :(得分:2)

我们成功使用TaskQueue的倒计时参数,在客户注册后7天向其发送电子邮件以及其他需求。

任务队列是核心/基本API /服务并且相当可靠 - 我认为这是使用任务队列ETA /倒计时的最佳方式,除非你:

  • 需要能力以编程方式查看队列中的内容
  • 需要能力以编程方式从队列中删除某些任务

答案 2 :(得分:1)

我正在使用任务队列作为调度程序。 QueueConstants中声明了最长30天,并在QueueImpl中应用。

  //Returns the maximum time into the future that a task may be scheduled.
  private static final long MAX_ETA_DELTA_MILLIS = 2592000000L;
  

1000ms * 60s * 60m * 24hr * 30days = 2592000000ms

 private long determineEta(TaskOptions taskOptions) {
Long etaMillis = taskOptions.getEtaMillis();
Long countdownMillis = taskOptions.getCountdownMillis();
if (etaMillis == null) {
  if (countdownMillis == null) {
    return currentTimeMillis();
  } else {
    if (countdownMillis > QueueConstants.getMaxEtaDeltaMillis()) {
      throw new IllegalArgumentException("ETA too far into the future");
    }
    if (countdownMillis < 0) {
      throw new IllegalArgumentException("Negative countdown is not allowed");
    }
    return currentTimeMillis() + countdownMillis;
  }
} else {
  if (countdownMillis == null) {
    if (etaMillis - currentTimeMillis() > QueueConstants.getMaxEtaDeltaMillis()) {
      throw new IllegalArgumentException("ETA too far into the future");
    }
    if (etaMillis < 0) {
      throw new IllegalArgumentException("Negative ETA is invalid");
    }
    return etaMillis;
  } else {
    throw new IllegalArgumentException(
        "Only one or neither of EtaMillis and CountdownMillis may be specified");
  }
}

}

答案 3 :(得分:0)

我执行以下操作:

  1. 按照您的提及配置延迟排队任务。让任务处理以已知方式更改数据存储条目(例如:设置标志)。

  2. 有一个落后者低频cron作业,执行任何已被排队任务遗漏的处理(例如:任务中发生未捕获的异常)。

  3. 为此,请确保task和cron作业调用的处理是幂等的。

    享受?

答案 4 :(得分:-1)

我认为taskQueue是一个很好的策略,但有一个大问题“如果成功创建了推送任务,它最终会被删除(最多在任务成功执行后七天)。” Source

我会使用datastore。这是您可以采取的一种策略:

  1. 完成“解析数据”后,将记录插入数据存储区。
  2. 根据创建/插入日期检查当前日期,以查看自作业完成/启动以来经过的时间等 (很明显,你不想每时每刻都这样做,也许你曾经做过一次 白天或每小时)
  3. 只要步骤2中的条件超出您想要的“任意时间”,就执行您需要执行的下一个任务。
  4. 以下是如何将记录添加到数据存储...以帮助您入门..

        Entity parsDataHolder = new Entity("parsing_data_done", guestbookKey);
        parsDataHolder.setProperty("date", date);
    
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    datastore.put(parsDataHolder)