可以在Google App Engine中增加响应超时时间吗?

6 投票
3 回答
7674 浏览
提问于 2025-04-15 23:25

在我的本地电脑上,这个脚本运行得很好,但在云端总是出现500错误。这是一个定时任务,所以我不太在意它是否需要5分钟……

< 类别 'google.appengine.runtime.DeadlineExceededError' >:

有没有人知道是否可以增加超时时间?

谢谢,
rui

3 个回答

1

下面是我用来解决这个问题的代码,方法是把一个大的查询拆分成多个小的查询。我使用了 google.appengine.ext.ndb 这个库——我不确定这是否是让下面的代码正常工作的必要条件。

(如果你没有使用 ndb,建议你考虑换用它。它是 db 库的改进版,迁移到这个库也很简单。想了解更多信息,可以查看 https://developers.google.com/appengine/docs/python/ndb。)

from google.appengine.datastore.datastore_query import Cursor

def ProcessAll():
  curs = Cursor()
  while True:
    records, curs, more = MyEntity.query().fetch_page(5000, start_cursor=curs)
    for record in records:
      # Run your custom business logic on record.
      RunMyBusinessLogic(record)
    if more and curs:
      # There are more records; do nothing here so we enter the 
      # loop again above and run the query one more time.
      pass
    else:
      # No more records to fetch; break out of the loop and finish.
      break
9

数据库查询的超时规则其实挺复杂的,但大致上来说,一个查询的时间不能超过大约2分钟,而一批查询的时间不能超过大约30秒。下面的代码展示了如何把一个任务分成多个查询,并使用游标来避免超时的问题。

def make_query(start_cursor):
  query = Foo()

  if start_cursor:
    query.with_cursor(start_cursor)

  return query

batch_size = 1000
start_cursor = None

while True:
  query = make_query(start_cursor)
  results_fetched = 0

  for resource in query.run(limit = batch_size):
    results_fetched += 1

    # Do something

    if results_fetched == batch_size:
      start_cursor = query.cursor()
      break
  else:
    break
10

你不能把超时时间设置得超过30秒,但你可以通过使用任务队列来间接增加超时时间。具体来说,你可以写一个任务,让它逐步处理你的数据集。每个这样的任务运行时,当然要确保它的时间在30秒的限制内。

编辑

更具体一点,你可以使用数据存储查询游标来在同一个地方继续处理:

http://code.google.com/intl/pl/appengine/docs/python/datastore/queriesandindexes.html#Query_Cursors

这个功能是在SDK 1.3.1中首次引入的:

http://googleappengine.blogspot.com/2010/02/app-engine-sdk-131-including-major.html

撰写回答