解决Django + Celery 长链接问题(一段时间后就断开) #原理待查

Posted shuo-yang0459

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决Django + Celery 长链接问题(一段时间后就断开) #原理待查相关的知识,希望对你有一定的参考价值。

技术背景: python(3.7) + Django(2.1) + Celery(4.2) + RabbitMQ(3.7.8)

启动环境

  • django runserver 启动在本地
  • celery 也是在本地系统:$ celery worker -A <project> -c 2 --loglevel=info -n ‘celery_worker_name‘ -Q <queue> -b amqp://****:****@localhost:*56**/vhost   //创建了一个新的vhost
  • rabbitmq 在docker 中启动,映射本地端口。

 

遇到的情况

 当webserver启动时,celery都可以正常工作,但是当有3min 没有添加 celery task. 所有的webserver 都可以调用celery_task.delay(). 但是celery并没有做任何的事情。

排查时,发现rabbitmq出现报错信息:

2019-02-02 07:07:00.679 [error] <0.731.0> closing AMQP connection <0.731.0> (172.17.0.1:34362 -> 172.17.0.4:5672):
missed heartbeats from client, timeout: 60s

 

快速解决方案: (不靠谱)

  重启webserver (这个解决方案太烂了。。不能让服务器一直重启吧。。或者一直保持有人调用吧。。。需要另寻出路)

 

原理待查!!!!!!


 

但是在搜索这个问题时,发现有小伙伴遇到同样的问题,并报bug(https://github.com/celery/celery/issues/4980)

所以需要找到一个靠谱的解决方案。

 

 >> 目前靠谱解决方案:

一般都是按照http://docs.celeryproject.org/en/v4.2.1/django/first-steps-with-django.html 这个文档配置celery on django (没有使用djcelery).

在 proj/proj/celry.py 添加如下配置内容(BROKER_HEARTBEAT): (根据https://www.cloudamqp.com/docs/celery.html)

 1 from __future__ import absolute_import, unicode_literals
 2 import os
 3 from celery import Celery
 4 
 5 # set the default Django settings module for the ‘celery‘ program.
 6 os.environ.setdefault(DJANGO_SETTINGS_MODULE, proj.settings)
 7 
 8 app = Celery(proj)
 9 
10 # Using a string here means the worker doesn‘t have to serialize
11 # the configuration object to child processes.
12 # - namespace=‘CELERY‘ means all celery-related configuration keys
13 #   should have a `CELERY_` prefix.
14 app.config_from_object(django.conf:settings, namespace=CELERY)
15 
16 
17 # 添加配置
18 # 关于这个参数,可以参考 http://docs.celeryproject.org/en/v4.2.1/userguide/configuration.html
19 # ----- 添加配置 -----------
20 app.conf.update(
21     BROKER_HEARTBEAT=None
22 )
23 # ----- 新的配置 -----------
24 
25 
26 # Load task modules from all registered Django app configs.
27 app.autodiscover_tasks()
28 
29 
30 @app.task(bind=True)
31 def debug_task(self):
32     print(Request: {0!r}.format(self.request))

 

// 但是rabbitmq会出现一些warning

2019-02-02 07:39:21.227 [warning] <0.1333.0> closing AMQP connection <0.1333.0> (172.17.0.1:35420 -> 172.17.0.4:5672, vhost: ‘vhost‘, user: ‘****‘):
client unexpectedly closed TCP connection

 

>>> 目前不会在出现之前的,3min无任务即无法再发送新任务了~~现在已经10min没有任务,但是却依然可以发送任务了~~~算是一个靠谱的解决方案。稳定性还需要再查。

 



以上是关于解决Django + Celery 长链接问题(一段时间后就断开) #原理待查的主要内容,如果未能解决你的问题,请参考以下文章

异步任务利器Celery介绍

Django + Celery:如何将带有参数的任务链接到周期性任务

解决 celery 和 django 中的循环导入问题

在 Django 1.11 中将 QuerySet 传递给 Celery 任务

如何在 Django 和 Celery 中配置多个代理?

django天天生鲜项目--------celery功能