## 一 场景
毕设中有个需求是定时更新各个用户的token,实现对token时效控制。由于我的web后台是基于django的,django默认是不允许这种独立进程的,这就需要celery这个异步队列大杀器了。
由于之前自己没有怎么做过celery,所以探索之中遇到一些坑,总结一下,避免自己再次碰到。
二 准备工作
1.参考资料
http://www.tuicool.com/articles/aIvYbie
http://blog.csdn.net/iloveyin/article/details/44940931
http://blog.liuts.com/post/248/
2.准备工作
安装相关软件
django、celery、djcelery,pip、下载源码安装都可以。
三 正式开始
1.打基础:什么是celery
“Celery是一个异步任务队列/基于分布式消息传递的作业队列。它侧重于实时操作,但对调度的支持也很好。”
celery主要解决两个问题:
a.回想一下你不得不在将来运行某一特定任务的经历。也许你需要每隔一小时访问一个API。 这个就是我的问题
b.你永远不希望终端用户等待那些不必要的页面加载或动作执行完成。 需要将任务加入队列,这样就不会将程序卡在那里了。
2.django项目部分
django不是本文的重点,django的日常操作,本文忽略
3.正戏开始了
a.project的setting.py增加如下配置:
import djcelery
djcelery. setup_loader()
BROKER_URL = 'django://'
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
INSTALLED_APPS = [
…………
'djcelery',
'kombu.transport.django',
]
TIME_ZONE = 'Asia/Shanghai'
此处主要是在配置文件中导入djcelery以及添加一些配置。生产环境下据说是不推荐’kombu.transport.django’,所以正式发布的时候还需要再摸索一下。
CELERYBEAT_SCHEDULER = ‘djcelery.schedulers.DatabaseScheduler’是用于定时任务时,将定时任务存储下来。
修改时区是为了定时任务时可以以北京时间开始。
b.在app文件夹下建立tasks.py
from celery import task
from models import DevUser
from celery.task.schedules import crontab
from celery.decorators import periodic_task
@task
def demo1(name):
print "hello:",name,"这是一个异步任务"
@periodic_task(run_every=(crontab(hour='20', minute='1')),ignore_result=True)
def demo2():
print "我将在20点01分执行"
修饰器很关键!
@task修饰的函数必须要有arguement参数,不然会故障
demo2的定时效果类似crontab的 1 20 * * * (minute,hour,day,dm,my)
c.调用task
虽然函数被@task修饰成一个task,但是仍然可以作为普通函数启动,如果作为异步队列调用,需要注意,像如下编写调用函数:
from your_app.tasks import demo1
demo1.delay()
需要进行delay一下,才能进入队列
python manage.py celery worker --loglevel=info
开启celery的worker,worker捕捉到队列里的任务就开始运行
d.定时任务开启
celery定时任务需要额外开启beat
python manage.py celery beat
这样,才能定时将任务加入队列,让worker捕捉。
除了像上文一样使用修饰器,还可以去http://127.0.0.1:8000/admin/djcelery/periodictask/ web页面进行配置。不过由于没找到有效资料,我只测试了修饰器里的用法。
4.生产环境部署
supervisord管理:
python manage.py celery beat
和
python manage.py celery worker --loglevel=info
这样关了窗口也能正常运行。关于supervisord的简单使用,见我另外的文章。
5.其他注意点
1.千万不要传递Django模型对象到celery任务。为了避免模型对象在传递给celery任务之前已经改变了,传递celery的主键给celery。然后,在运行之前使用主键从数据库中获取对象。
2.“celerybeat-schedule.db”和“celerybeat.pid”是celery调度在本地创建一些文件存储它的调度表
四 总结
对celery还不是特别了解,这篇文章算是下午对celery摸索结果的小结。