Django Celery 连接错误:心跳丢失过多
问题
我该如何解决来自 Celery 的 ConnectionError: Too many heartbeats missed
错误?
示例错误
[2013-02-11 15:15:38,513: ERROR/MainProcess] Error in timer: ConnectionError('Too many heartbeats missed', None, None, None, '')
Traceback (most recent call last):
File "/app/.heroku/python/lib/python2.7/site-packages/celery/utils/timer2.py", line 97, in apply_entry
entry()
File "/app/.heroku/python/lib/python2.7/site-packages/celery/utils/timer2.py", line 51, in __call__
return self.fun(*self.args, **self.kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/celery/utils/timer2.py", line 153, in _reschedules
return fun(*args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/kombu/connection.py", line 265, in heartbeat_check
return self.transport.heartbeat_check(self.connection, rate=rate)
File "/app/.heroku/python/lib/python2.7/site-packages/kombu/transport/pyamqp.py", line 134, in heartbeat_check
return connection.heartbeat_tick(rate=rate)
File "/app/.heroku/python/lib/python2.7/site-packages/amqp/connection.py", line 837, in heartbeat_tick
raise ConnectionError('Too many heartbeats missed')
ConnectionError: Too many heartbeats missed
应用概述
- 这是一个使用 Celery 处理定时后台任务的 Django 应用
- 托管在 Heroku 上
- 有一个任务设置为每 15 分钟运行一次,通过设置 / celerybeat 来安排
- 消息通过 CloudAMQP 插件处理
- 进程运行方式如下:
web: newrelic-admin run-program gunicorn --workers=2 --worker-class=gevent someapp.wsgi:application
scheduler: newrelic-admin run-program python manage.py celery worker -B -E --maxtasksperchild=1000 --loglevel=WARNING
包版本
我认为相关的版本如下:
Django==1.4.3
amqp==1.0.8
billiard==2.7.3.20
celery==3.0.14
gevent==0.13.8
greenlet==0.4.0
kombu==2.5.6
raven==3.1.10
我目前尝试过的解决方法
- 将错误与活动进行关联(似乎与用户访问应用、后台任务调用或应用闲置没有关联)
- 在网上搜索,直到手指麻木
- 将软件包升级到最新版本
- 进行不同级别的日志记录
- 使用 Sentry 捕获异常(在 Sentry 中没有出现)
- 在本地开发环境中无法重现此错误,只在 Heroku 的生产环境中出现
可能相关的信息
- 我不太确定这个错误是什么时候第一次出现的(大约一个月前?)
- 可能与以下更改有关(在此之前不记得有过这个错误,但不太确定)
celery==3.0.13
升级到celery==3.0.14
amqplib
更改为amqp
kombu==2.4.8
升级到kombu==2.5.4
- 错误只出现在日志中(没有被 New Relic 或 getsentry.com 捕捉到)
1 个回答
9
这个问题发生的频率有多高呢?
可能是你的心跳监测功能没有正常工作。心跳支持是最近才引入的,所以可能会有一些bug。我这边无法重现这个问题,所以我需要更多的信息来搞清楚发生了什么。
你可以通过设置 BROKER_HEARTBEAT=0
来关闭心跳功能。如果这是个bug的话,工作程序应该能正常运行,但它就无法快速发现连接断开了。在某些环境下,无法检测到连接丢失是个问题(通常是因为特定的路由器或防火墙设置造成的)。