App Engine生成无限重试

时间:2016-07-07 18:21:51

标签: google-app-engine

我有一个后端,通常由cron调用,每天运行几次。昨天,我注意到它正在重新启动而没有停止。我在代码中没有看到调用发生的位置。相反,任务队列似乎表明由于错误而重新尝试它正在运行。一个错误是状态被保存到bigQuery并且因为超出了引号而失败。但这似乎产生了无限循环。这是app引擎中的错误还是我做错了什么?有没有办法表明如果失败则不重启任务?我没有200状态终止的其他应用程序引擎任务不会这样做......

以下是重启持续发生的队列的跟踪:enter image description here

这是显示连续运行的日志记录 enter image description here

这是日志记录中的http标头 enter image description here

UPDATE1 这是cron:

<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
    <url>/uploadToBigQueryStatus</url>
    <description>Check fileNameSaved Status</description>
    <schedule>every 15 minutes from 02:30 to 03:30</schedule>
    <timezone>US/Pacific</timezone>
    <target>checkuploadstatus-backend</target>
</cron>
</cronentries>

更新2 关于捕获错误的评论:我认为错误是biqQuery作业失败,因为配额已被命中。奇怪的是,它发生在昨天,配额应该已经重置,所以错误应该至少有一段时间。我不明白为什么任务重试,我从未选择我所知道的那个选项。

我杀死了servlet并清空了任务队列,至少它被停止了。但我不知道根本原因。如果BQ表配额是原因,那不应该导致无限重试!

更新3 我没有捕获产生导致无限重试的错误的servlet调用。但我今天检查了这个cron激活的servlet,发现我有另一个非200的结果。此时的返回值为500,它是由DataStore超时异常引起的。

以下是显示500返回代码的返回的屏幕截图。 enter image description here

这是异常信息页面1 enter image description here

以下数据 enter image description here

违规代码行是for循环迭代数据存储查询

        if (keys[0] != null) {

            /* Define the query */
            q = new Query(bucket).setAncestor(keys[0]);

            pq = datastore.prepare(q);
            gotResult = false;

            // First system time stamp
            Date date= new Timestamp(new Date().getTime());
            Timestamp timeStampNow = new Timestamp(date.getTime());

            for (Entity result : pq.asIterable()) {

我将在for循环中添加一个try-catch,因为它在此迭代中崩溃。

        if (keys[0] != null) {

            /* Define the query */
            q = new Query(bucket).setAncestor(keys[0]);

            pq = datastore.prepare(q);
            gotResult = false;

            // First system time stamp
            Date date= new Timestamp(new Date().getTime());
            Timestamp timeStampNow = new Timestamp(date.getTime());

            try {

                for (Entity result : pq.asIterable()) {

希望读取的数据存储不会使servlet崩溃,但会导致失败。在leas处,cron将再次运行并获取其他未处理的结果。 顺便说一句,这是一个java错误或应用程序引擎?我看到很多这些数据存储超时,我将在所有结果循环周围添加try-catch。不过,它不应该导致我经历的无限重试。我会看看我是否能找到真正的崩溃问题。问题是它重载了我的日志...更多以后。

更新4 我回到原木看看无限循环何时开始。在下面的日志中,我打开了连续运行头部的运行。你可以看到它每5次失败500次。它不是调用它的cron,我调用servlet检查biq查询上传状态(我写入数据存储作业信息,然后在servlet中读回来并写​​入bigQuery作业状态,如果完成,擦除数据存储条目。)我无法解释每5次调用的稳定500错误,但始终是数据存储超时异常。 enter image description here

更新5 由于队列配置,可以进行无限重试吗?              CheckUploadStatus         20 / s的         10         100                      10             200             2               我刚刚注意到另一个任务队列有500个返回代码并且它一直在重试。我做了一些搜索,发现有些人试图配置 队列没有重试。他们说没有用。
看到这个链接: Google App Engine: task_retry_limit doesn't work?  但有一次重试是可能的吗?这比无限好得多。

Google强制执行配额,但似乎更喜欢无限重试,这是矛盾的。我更喜欢在非200返回代码上默认阻止重试,然后没有QUOTAS !!!

1 个答案:

答案 0 :(得分:0)

根据Retrying cron jobs that fail

  

如果cron作业的请求处理程序返回不在的状态代码   范围200-299(含)App Engine认为该工作有   失败。默认情况下,不会重试失败的作业。

     

设置要重试的失败作业:

     
      
  1. 在cron.xml文件中包含重试参数块。
  2.   
  3. 在重试参数块中选择并设置重试参数。
  4.   

您的cron配置没有指定必要的重试参数,因此返回500代码的作业确实不会像您期望的那样重试。

所以这看起来像个bug。可能是(较旧的)known issue 10075的变体 - 提到的503代码可能在平均时间内发生了变化 - 但它也是与配额相关的失败。

GAEfan评论的建议可能是一个很好的解决方法:

  

您将需要捕获错误,并发送200响应以停止   任务队列重试。 - GAEfan 1小时前