我遇到了一个很难追查的错误,所以我想我会在这里添加原因+“解决方案”。AppEngine:开始任务时发生的gaierror
设置: Devbox - 运行Google App Engine监听所有启动任务的URL的端口(“--address = 0.0.0.0”)。 客户端 - 客户端(Python的请求库)的查询回调URL
应用程序引擎代码:
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
此错误只会在任务重试时循环旋转。虽然很奇怪,我可以去管理 - >任务队列,然后点击'运行',让任务成功完成。
起初我以为这是一个绑定错误。如果我通过浏览器查询StartTaskCallback,或者本地运行客户端,我不会收到错误。
最后,我注意到App Engine正在使用请求的'host'字段来为该任务构建绝对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 因此,远程客户端的“主机”看起来像本地服务器无法解析的“devbox:8085”。
我真的不清楚你在这里做什么。什么是“远程客户端”,它在做什么?我假设你正在从其他机器获取排队任务的URL,但是这与任务重试有什么关系呢? – 2012-03-24 09:52:57
是的,这是一个简单的应用程序,在获取某个URL时启动任务,并且试图在我的本地开发环境(在Macbook上运行的GoogleAppEngineLauncher)中对其进行测试。这里的技巧是,获取URL的客户机是另一台机器(具有不同的IP地址),而不是通过dev_appserver通常绑定的环回的浏览器。 – 2012-03-26 22:42:31
该任务失败,因为AppEngine在其HTTP请求中使用客户端提供的主机名来为任务生成绝对URL。如果客户端使用在其hosts文件中定义的名称,那么当服务器无法解析名称时,将无法在服务器上创建该任务。 – 2012-03-26 22:45:54