我在 Heroku 上有一个 Django 应用程序,它使用 Celery 的延迟方法调用任务,它应该将额外的处理传递给工作人员。但是当我向相应的视图发出 http 请求时,Heroku web dyno 挂起并最终导致请求超时。这是一个测试任务(该应用程序称为等待时间):
@task
def test_tasks(message, name='waittimes.tasks.test_tasks'):
print message
和测试视图:
class TaskTest(View):
def get(self, request):
print "about to call the task"
test_tasks.delay("the task was successful!")
return HttpResponse("view was successful")
如果我向该视图发出 http 请求,我希望“任务成功”会输出到控制台,并会返回“视图成功”的响应。当我向计算机上的开发服务器发出请求时,这会成功发生。如果我在我的应用程序的 Heroku 环境中启动一个 django shell 并使用 django 的测试客户端发出请求,它也可以工作。
app[celeryd.1]: [2013-06-26 23:57:48,018: INFO/MainProcess] Got task from broker: waittimes.tasks.test_tasks[67036069-b49e-45ba-aef4-3c64d7161a67]
app[celeryd.1]: [2013-06-26 23:57:48,133: WARNING/PoolWorker-3] the task was successful!
app[celeryd.1]: [2013-06-26 23:57:48,200: INFO/MainProcess] Task waittimes.tasks.test_tasks[67036069-b49e-45ba-aef4-3c64d7161a67] succeeded in 0.09690284729s: None
但是当我直接向 Heroku url 发出请求时,请求挂起,我最终从 Heroku 收到了一个可怕的 H12 超时错误。
heroku[router]: at=error code=H12 desc="Request timeout" method=GET path=/task/test/ dyno=web.1 connect=2ms service=30000ms status=503 bytes=0
我知道调用任务会导致问题,因为“即将调用任务”确实会打印在控制台中。所以问题是系统无法解决“延迟”(和apply_async)方法。它只是挂起并且不返回异步对象。这只发生在代码在 web dyno 进程上运行时。
到目前为止,这些是我的结论:
1) 任务已正确注册并且我的 Redis 代理正在工作,因为当我从 shell 使用测试客户端调用视图时一切正常(但是这是在 Heroku 上的单独 shell 进程上运行,而不是在通常接收请求的 web dyno 上运行)
2) 系统正确路由和分派请求的处理程序,因为“即将调用任务”被打印出来。Heroku路由器似乎没有问题。
3)问题与特定视图无关,因为即使是这样的精简测试用例也不起作用
除了直接的解决方案之外,还感谢任何有关如何进一步调试的建议。