【问题标题】:AppEngine Timeout with Task Queues带有任务队列的 AppEngine 超时
【发布时间】:2013-11-14 15:41:02
【问题描述】:

我正在尝试通过任务队列在 AppEngine 中执行一项任务,但我似乎仍然面临 60 秒的超时。我不确定自己做错了什么,因为我认为广告中的限制应该是 10 分钟。

我打电话给urlfetch.fetch(),这似乎是罪魁祸首。我的电话是:

urlfetch.fetch(url, payload=query_data, method=method, deadline=300)

我的堆栈跟踪的尾部显示了在 DeadlineExceededError 之前触发 url fetch 调用的方法:

File "/base/data/home/apps/s~mips-conversion-scheduler/000-11.371629749593131630/views.py", line 81, in _get_mips_updated_data
policies_changed = InquiryClient().get_changed_policies(company_id, initial=initial).json()

当我查看它显示的任务队列信息时:

Method/URL: POST /tasks/queue-initial-load
Dispatched time (UTC): 2013/11/14 15:18:49
Seconds late: 0.18
Seconds to process task: 59.90
Last http response code: 500
Reason to rety: AppError

处理任务的我的视图如下所示:

class QueueInitialLoad(webapp2.RequestHandler):
def post(self):
    company = self.request.get("company")
    if company:
        company_id = self.request.get("company")
        queue_policy_load(company_id, queue_name="initialLoad", initial=True)

queue_policy_load 是触发 urlfetch 调用的方法。

有什么明显的我遗漏的东西使我被限制在 60 秒而不是 10 分钟?

【问题讨论】:

    标签: python google-app-engine


    【解决方案1】:

    可能有点过于笼统,但这里有一些想法可能有助于结束循环。任务队列有两种,推送队列和拉取队列。推送队列任务会自动执行,并且它们仅适用于您的 App Engine 应用程序。另一方面,拉队列任务等待租用,可供应用程序外部的工作人员使用,并且可以批量处理。

    如果要配置队列,可以在队列配置文件中进行。在 Java 中,这发生在 queue.xml 文件中,而在 Python 中,发生在 queue.yaml 文件中。具体就推送队列而言,推送队列任务由处理程序 (URL) 作为 POST 请求进行处理。他们:

    1. 尽快执行
    2. 可能会导致新实例(前端或后端)
    3. 任务持续时间限制为 10 分钟
    4. 但是,如果任务在后端运行,则它们的持续时间不受限制

    这是一个快速的 Python 代码示例,展示了如何将任务添加到命名推送队列。如果您需要更多信息,请查看任务队列的 Google 开发人员页面:https://developers.google.com/appengine/docs/python/taskqueue/

    将任务添加到命名推送队列:

    queue = taskqueue.Queue("Qname")
    task = taskqueue.Task(url='/handler', params=args)
    queue.add(task)
    

    另一方面,假设您想使用拉取队列。您可以使用以下命令将 Python 中的任务添加到拉取队列:

    queue = taskqueue.Queue("Qname")
    task = taskqueue.Task(payload=load, method='PULL')
    queue.add(task)
    

    然后您可以在 Python 中使用以下方法租用这些任务:

    queue = taskqueue.Queue("Qname")
    tasks = queue.lease_tasks(how-long, how-many)
    

    请记住,对于拉取队列,如果任务失败,App Engine 会重试它,直到成功。

    希望在提供一般观点方面有所帮助!

    【讨论】:

      【解决方案2】:

      任务队列有 10 分钟的期限,但 Urlfetch 调用有 1 分钟的期限:

      maximum deadline (request handler) 60 seconds

      更新:预期的行为是在任务队列中运行时 URLFetch 的截止时间最长为 10 分钟,请参阅此bug

      【讨论】:

      • 感谢您的快速回复。那些相同的文档(在 python 端)状态:“您可以为请求设置截止日期,服务将等待响应的最长时间。默认情况下,获取的截止日期为 5 秒。最大截止日期为HTTP 请求 60 秒,任务队列和 cron 作业请求 10 分钟。”我是不是误解了这意味着什么?
      • 因为一个任务可以运行 10 分钟,而不是它可以发出持续的 HTTP 请求。
      • @PaulCollingwood - 感谢您的回复。这是否意味着无法发出运行时间超过 60 秒的外部请求?
      • NP。据我所知,没有,快速浏览一下通常的地方也说没有。我想您可以在每个请求上获取/发送部分内容作为解决方法。
      • 它更微妙。 TaskQueues 上 URLFetch 的截止日期原定为 10 分钟,但这个错误 code.google.com/p/googleappengine/issues/detail?id=10470 毕竟使答案正确。
      【解决方案3】:

      随着 GAE 的发展,此答案适用于今天已弃用“后端”实例的想法。 GAE 应用程序可以配置为服务(又名模块)并使用manual 扩展策略运行。这样做可以设置更长的超时时间。如果您使用 autoscaling 策略运行您的应用程序,它会将您的 urlfetch 限制为 60 秒,并将您的排队任务限制为 10 分钟: https://cloud.google.com/appengine/docs/python/an-overview-of-app-engine

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-17
        • 1970-01-01
        • 2013-09-18
        • 1970-01-01
        • 2011-06-23
        • 2011-01-25
        相关资源
        最近更新 更多