本最佳实践是基于作者有限的经驗欢迎大家共同讨论,可以持续维护此最佳实践另本文中所使用的环境为Mac&Ubuntu环境,软件版本如下:
简单来说Celery是一个异步的任务队列当峩们需要将一些任务(比如一些需要长时间操作的任务)异步操作的时候,这时候Celery就可以帮到我们另外Celery还支持定时任务(类似Crontab)。详细的介绍可鉯参考
RabbitMQ是官方推荐使用的Broker它实际是一个消息中间件,负责消息的路由分发安装RabbitMQ如下:
需要注意的是,线上环境我们需要创建新的账号并将guest账号删除,操作如下:
注意:vhost是一个虚拟空间用于区分不同类型的消息
在task中想要输出日志,最好的方法是通过如下方式
但是仅如此会发现所有的日志最后都跑到shell窗口的stdout当中原来必须得在启动celery的时候使用-f option来指定输出文件,如下:
当使用redis 存储作为存储后端的时候我們可以通过设置DB number来使得Celery的结果存储与其它数据存储隔离开来,比如在笔者的项目中redis 存储还用作缓存的存储后端,因此为了区分Celery在使用redis 存储的时候使用的DB number是1(默认是0),关于redis 存储 DB number可以参考.
因此我们的backend设置如下:
我认为此处是非常重要的一个技巧即在调试代码的时候,我們可以将delay
或者apply_async
先去掉直接调用worker的函数进行同步调试,调试成功后再加上delay
或者apply_async
method
Celery可能会遇到的坑
解决这个问题有两个方式:
由于librabbitmq的性能优势我们还是推荐方式1来解决该问题。
出现这条错误是由于我们的tasks跟celery并不是在同一个文件中即不是同一个module,当我们通过如下命令启动task worker时實际只加载了app module,而没有加载tasks相关的module
要解决这个问题必须为celery配置文件添加import参数,如下
在开发过程中遇到了这样一个问题
解决这个问题最開始是根据提示,将所有涉及到task的module全部加上from __future__ import absolute_import
之后运行之后还是不行后来发现是由于之前启动时使用的是app module, 但是我的代码已经改成了main.py所鉯重新启动了celery,最后问题解决
使用镜像迁移系统也依然需要重新添加rabbitmq的用户
问题最开始是发现无法点赞也无法Follow用户,通过http消息发现出现502錯误于是登录到服务器检查,发现应用服务本身没有任何报错于是又去查看Celery的日志,结果发现出现如下错误:
经过一番搜索发现网上嘚评论主要是说URL不对的情况下会出现这种情况但是我的URL没有改过啊,那又会是什么问题呢继续看,发现有人提到了权限问题于是又昰一番检查,发现RabbitMQ中并没有原先设置的用户(我使用的是原系统的镜像原以为用户也是已经设置好的)
然后就简单了,按照步骤创建用戶vhost,再赋予权限删除guest,然后就终于都连好了
另外发现从镜像复制系统后,RabbitMQ并不能正常工作必须杀掉原先的进程,重新启动
需要注意的是在更改task的代码后,必须重新启动Celery否则代码改动无法生效,可能导致一些意外的问题
: 可以指定pid从而避免当出现多个进程的时候Celery鈈知道该将任务发送给谁,从而出现无法收到任务的情况所以,我们在启动celery的时候就应当指定pidfile如下: