【发布时间】:2012-04-08 11:17:48
【问题描述】:
我遇到了一个很难追查的错误,所以我想我应该在这里添加原因+“解决方案”。
设置: Devbox - 运行 Google App Engine 侦听所有端口(“--address=0.0.0.0”),为启动任务的 URL 提供服务。 Client - 查询回调 URL 的客户端(Python 请求库)
App 引擎代码:
class StartTaskCallback(webapp.RequestHandler):
def post(self):
param = self.request.get('param')
logging.info('STARTTASK: %s' % param)
# launch a task
taskqueue.add(url='/tasks/mytask',
queue_name='myqueue',
params={'param': param})
class MyTask(webapp.RequestHandler):
def post(self):
param = self.request.get('param')
logging.info('MYTASK: param = %s' % param)
当我使用浏览器查询回调时,一切正常,但来自远程客户端的相同查询给了我以下错误:
ERROR 2012-03-23 21:18:27,351 taskqueue_stub.py:1858] An error occured while sending the task "task1" (Url: "/tasks/mytask") in queue "myqueue". Treating as a task error.
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/taskqueue/taskqueue_stub.py", line 1846, in ExecuteTask
connection.endheaders()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/httplib.py", line 868, in endheaders
self._send_output()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/httplib.py", line 740, in _send_output
self.send(msg)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/httplib.py", line 699, in send
self.connect()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/httplib.py", line 683, in connect
self.timeout)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/socket.py", line 498, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
gaierror: [Errno 8] nodename nor servname provided, or not known
当任务重试时,这个错误只会在一个循环中旋转。虽然奇怪,但我可以转到 Admin -> Task Queues 并单击“Run”以使任务成功完成。
起初我认为这是绑定错误。如果我通过浏览器查询 StartTaskCallback 或者我在本地运行客户端,我不会收到错误。
最后我注意到 App Engine 正在使用请求的“主机”字段来为任务构建绝对 URL。在 /Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/taskqueue/taskqueue_stub.py (1829):
connection_host, = header_dict.get('host', [self._default_host])
if connection_host is None:
logging.error('Could not determine where to send the task "%s" '
'(Url: "%s") in queue "%s". Treating as an error.',
task.task_name(), task.url(), queue.queue_name)
return False
connection = httplib.HTTPConnection(connection_host)
就我而言,我在远程客户端上使用特殊名称 + 主机文件来访问服务器。 192.168.1.208 开发箱 所以远程客户端的“主机”看起来像本地服务器无法解析的“devbox:8085”。
【问题讨论】:
-
我真的不清楚你在这里做什么。什么是“远程客户端”,它在做什么?我假设您正在从另一台机器获取将任务排入队列的 URL,但这与任务重试有什么关系?
-
是的,它是一个简单的应用程序,它在获取某个 URL 时启动一个任务,我试图在我的本地开发环境中测试它(GoogleAppEngineLauncher 在 Macbook 上运行)。这里的技巧是获取 URL 的客户端是另一台机器(具有不同的 IP 地址),而不是 dev_appserver 通常绑定的环回上的浏览器。
-
任务失败,因为 AppEngine 使用客户端在其 HTTP 请求中提供的主机名来生成任务的绝对 URL。如果客户端使用其 hosts 文件中定义的名称,当无法解析名称时,任务将无法在服务器上创建。
-
如果您有解决方案,您应该将其发布为您自己问题的答案,而不是作为问题的一部分。并且一定要针对 SDK 提交错误!