1.定义:

Celery是一个异步的任务队列(也叫做分布式任务队列)

2.工作结构

Celery分为3个部分

(1)worker部分负责任务的处理,即工作进程(我的理解工作进程就是你写的python代码,当然还包括python调用系统工具功能)

(2)broker部分负责任务消息的分发以及任务结果的存储,这部分任务主要由中间数据存储系统完成,比如消息队列服务器RabbitMQ、redis、Amazon SQS、MongoDB、IronMQ等或者关系型数据库,使用关系型数据库依赖sqlalchemy或者django的ORM

(3)Celery主类,进行任务最开始的指派与执行控制,他可以是单独的python脚本,也可以和其他程序结合,应用到django或者flask等web框架里面以及你能想到的任何应用

3.话不多说,用起来

(1)安装Celery(要安装celery3版本,4版本改动较大没测试)

  1. pip install celery==3.1.17

(2)broker部分此处使用安装好的redis服务6380端口的db0作为消息队列,普通redis服务的安装此处不做介绍

(3)Celery的使用一(单独脚本调用,简单方便)

注:不考虑任务的结果存储情况

<1>/tmp/tasks.py(实际脚本中不要写中文注释)

  1. #!/usr/bin/env python
  2.  
  3. # -*- coding=utf-8 -*-
  4.  
  5. from celery import Celery
  6.  
  7. from celery import platforms
  8.  
  9. #用于开启root也可以启动celery服务,默认是不允许root启动celery的
  10.  
  11. platforms.C_FORCE_ROOT = True
  12.  
  13. #创建一个celery实例,传递进去的第一个参数tasks必须是本文件的文件名tasks,指定broker为本机redis6380服务
  14.  
  15. celery = Celery('tasks', broker='redis://localhost:6380/0')
  16.  
  17. #使用celery实例的task装饰器装饰add函数,此处的add函数可以当作后期的耗时任务对待
  18.  
  19. @celery.task
  20.  
  21. def add(x,y):
  22.  
  23. return x + y

<2>启动celery服务

  1. #cd /tmp
  2.  
  3. #celery -A tasks worker --loglevel=info

<3>验证执行任务

导入模块,执行add函数,此处使用add.delay(3,4)而不是add(3,4),因为被celery封装了,要异步执行需要额外使用add.delay(3,4)

需要注意,如果把返回值赋值给一个变量,那么原来的应用程序也会被阻塞,需要等待异步任务返回的结果。因此,实际使用中,不需要把结果赋值。

  1. #cd /tmp
  2.  
  3. #python
  4.  
  5. >>>from tasks import add
  6.  
  7. >>>add.delay(3,4)

celery服务的窗口会刷出任务的信息,以及是否处理成功,以及结果

 
 

将来只要在别的程序中引入tasks中的add函数,就是异步的了,是不是有点屌。。。。。

<4>扩展知识,指定队列名

传入redis中的指定队列testq怎么玩?(其他broker引擎也支持)

启动celery服务的时候添加额外参数-Q '队列名'

  1. #cd /tmp
  2.  
  3. #celery -A tasks.tasks worker --loglevel=info -Q 'testq'

跑任务的时候指定testq队列名

  1. #cd /tmp
  2.  
  3. #python
  4.  
  5. >>>from tasks import add
  6.  
  7. >>>add.delay(3,4,queue='testq')

<5>扩展知识,指定开启的worker进程数(底层是调用的Python的multiprocessing模块中的Pool进程池思想来做)

-c 5 开启5个worker进程来同时抢任务,跑任务

  1. #cd /tmp
  2.  
  3. #celery -A tasks.tasks worker --loglevel=info -c 5

<6>扩展知识,管理broker里面的数据,查看任务状态,以及任务的详细信息

安装一个叫flower的webui,提供任务查询,worker生命管理,以及路由管理等(底层是通过tornado框架封装的)

  1. #pip install flower
  2.  
  3. #任意目录下执行都可以
  4.  
  5. #celery flower --port=5555 --broker=redis://localhost:6380/0

里面可以看到任务参数,结果,接受任务时间,任务开始时间,任务状态,Started是任务进行中,Success是任务跑完执行成功

 
 

(4)Celery的使用二(项目方式,也叫做Python包方式,结构清晰,低耦合;相比纯脚本方式略复杂,用不用由你)

创建一个叫做proj的Python包(创建Python包的操作此处不做详细说明,tree /tmp/proj)

 

<1>proj/celery.py

from __future__ import absolute_import 据说添加此行可以低降低出错的概率哦(阿门保佑;其实就是兼容Python版本的一个东东)

创建一个celery的实例,名字叫做app,传递进去的第一个参数是Python包的名字,include加载任务文件,config_from_object指定celery的配置文件(好吧,看起来比单纯使用脚本方式麻烦点,请继续往下看)

  1. #!/usr/bin/env python
  2.  
  3. # -*- coding=utf-8 -*-
  4.  
  5. from __future__ import absolute_import
  6.  
  7. from celery import Celery
  8.  
  9. app = Celery('proj', include=['proj.tasks'])
  10.  
  11. app.config_from_object('proj.config')
  12.  
  13. if __name__ == '__main__':
  14.  
  15. app.start()

<2>proj/config.py

配置文件里指定broker

  1. #!/usr/bin/env python
  2.  
  3. # -*- coding:utf-8 -*-
  4.  
  5. from __future__ import absolute_import
  6.  
  7. BROKER_URL = 'redis://127.0.0.1:6380/0'

<3>proj/tasks.py

导入celery实例,实例绑定任务

  1. #!/usr/bin/env python
  2.  
  3. # -*- coding:utf-8 -*-
  4.  
  5. from __future__ import absolute_import
  6.  
  7. from proj.celery import app
  8.  
  9. @app.task
  10.  
  11. def add(x, y):
  12.  
  13. return x + y

<4>开启celery服务(特定目录指定包名字启动)

  1. #cd /tmp/
  2.  
  3. #celery -A proj worker -l info

<5>扩展功能,指定队列名,调整worker进程数,页面管理celery同上,不再做说明

(5)Celery的使用三(django-celery模式;#反正我喜欢用这种)

django调用celery跑异步任务,常见场景有注册成功,发送邮件可以异步来防止网络IO阻塞,以及耗时间的任务,例如需要去跑9000台IP的某些配置参数任务,或者下发任务执行,可能需要10几分钟才能跑完,就可以WEB应用中使用这种异步方式

<1>安装django-celery软件包

一定要注意celery的版本和django-celery的小版本要保持一致,否则会有各种杂七杂八的小问题(都是泪.......)

  1. #pip install celery==3.1.17
  2.  
  3. #pip install django-celery==3.1.17

<2>创建celery必须的数据库表结构

  1. #cd Python_20161203
  2.  
  3. #python manage.py migrate

<3>django项目的settings.py文件中追加如下内容;app呢是django项目里面的应用名字

settings.py

  1. import djcelery
  2.  
  3. djcelery.setup_loader()
  4.  
  5. BROKER_URL = 'redis://127.0.0.1:6380/0'
  6.  
  7. CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6380/1'
  8.  
  9. CELERY_TASK_SERIALIZER = 'json'
  10.  
  11. CELERY_RESULT_SERIALIZER = 'json'
  12.  
  13. CELERY_ACCEPT_CONTENT = ['json']
  14.  
  15. CELERY_IMPORTS = ('app.tasks', )
  16.  
  17. CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
  18.  
  19. CELERYD_CONCURRENCY = 20

参数说明(可以根据自己的需求添加自己的参数):

CELERY_RESULT_BACKEND = "redis://127.0.0.1:6380/1'" #结果存储

CELERY_TASK_RESULT_EXPIRES = 1200 # celery任务执行结果的超时时间,我的任务都不需要返回结果,只需要正确执行就行

CELERYD_CONCURRENCY = 20 # celery worker的并发数 也是命令行-c指定的数目,事实上实践发现并不是worker也多越好,保证任务不堆积,加上一定新增任务的预留就可以

CELERYD_PREFETCH_MULTIPLIER = 4 # celery worker 每次去redis取任务的数量,我这里预取了4个慢慢执行,因为任务有长有短没有预取太多

CELERYD_MAX_TASKS_PER_CHILD = 200 # 每个worker执行了多少任务就会死掉,我建议数量可以大一些,比如200

CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler' # 这是使用了django-celery默认的数据库调度模型,任务执行周期都被存在你指定的orm数据库中

 

<4>app/tasks.py(在django的app应用目录下创建tasks.py任务文件,里面调用复杂的任务函数)

  1. #!/usr/bin/env python
  2.  
  3. # -*- coding=utf-8 -*-
  4.  
  5. ###############################
  6.  
  7. from __future__ import absolute_import
  8.  
  9. from celery import task
  10.  
  11. import time
  12.  
  13. #task装饰器封装了celery函数,为耗时的操作
  14.  
  15. @task
  16.  
  17. def add(x,y):
  18.  
  19. for i in range(30):
  20.  
  21. print i
  22.  
  23. time.sleep(1)
  24.  
  25. return x + y

<5>添加验证功能,查看实际效果
app/urls.py

  1. urlpatterns = [
  2.  
  3. url(r'^celery_test/,views.celery_test),
  4.  
  5. ]

app/views.py

  1. def celery_test(request):
  2.  
  3. from tasks import add
  4.  
  5. add.delay(4,8)
  6.  
  7. return HttpResponse('Celery testing666')

<6>开启djanog服务和celery服务(虽然耦合了,但是还是需要额外开启)

  1. #python manage.py runserver 0.0.0.0:8000
  2.  
  3. #另一个窗口开启celery服务
  4.  
  5. #python manage.py celery worker --loglevel=info

<7>发送http的GET请求,调用celery去执行异步任务(大功告成)

curl http://127.0.0.1:8000/index/celery_test/

celery那端的屏幕输出如下:

  1. [2016-12-01 16:16:00,940: INFO/MainProcess] Received task: app.tasks.add[06a8d603-a7d3-4732-b8f3-ad010d531200]
  2.  
  3. [2016-12-01 16:16:00,941: WARNING/Worker-1] 0
  4.  
  5. [2016-12-01 16:16:01,943: WARNING/Worker-1] 1
  6.  
  7. [2016-12-01 16:16:02,945: WARNING/Worker-1] 2
  8.  
  9. [2016-12-01 16:16:03,947: WARNING/Worker-1] 3
  10.  
  11. [2016-12-01 16:16:04,948: WARNING/Worker-1] 4
  12.  
  13. [2016-12-01 16:16:05,950: WARNING/Worker-1] 5
  14.  
  15. [2016-12-01 16:16:06,952: WARNING/Worker-1] 6
  16.  
  17. [2016-12-01 16:16:07,954: WARNING/Worker-1] 7
  18.  
  19. [2016-12-01 16:16:08,955: WARNING/Worker-1] 8
  20.  
  21. [2016-12-01 16:16:09,957: WARNING/Worker-1] 9
  22.  
  23. [2016-12-01 16:16:10,958: WARNING/Worker-1] 10
  24.  
  25. [2016-12-01 16:16:11,959: WARNING/Worker-1] 11
  26.  
  27. [2016-12-01 16:16:12,961: WARNING/Worker-1] 12
  28.  
  29. [2016-12-01 16:16:13,962: WARNING/Worker-1] 13
  30.  
  31. [2016-12-01 16:16:14,964: WARNING/Worker-1] 14
  32.  
  33. [2016-12-01 16:16:15,964: WARNING/Worker-1] 15
  34.  
  35. [2016-12-01 16:16:16,966: WARNING/Worker-1] 16
  36.  
  37. [2016-12-01 16:16:17,968: WARNING/Worker-1] 17
  38.  
  39. [2016-12-01 16:16:18,969: WARNING/Worker-1] 18
  40.  
  41. [2016-12-01 16:16:19,971: WARNING/Worker-1] 19
  42.  
  43. [2016-12-01 16:16:20,973: WARNING/Worker-1] 20
  44.  
  45. [2016-12-01 16:16:21,974: WARNING/Worker-1] 21
  46.  
  47. [2016-12-01 16:16:22,976: WARNING/Worker-1] 22
  48.  
  49. [2016-12-01 16:16:23,978: WARNING/Worker-1] 23
  50.  
  51. [2016-12-01 16:16:24,979: WARNING/Worker-1] 24
  52.  
  53. [2016-12-01 16:16:25,981: WARNING/Worker-1] 25
  54.  
  55. [2016-12-01 16:16:26,982: WARNING/Worker-1] 26
  56.  
  57. [2016-12-01 16:16:27,984: WARNING/Worker-1] 27
  58.  
  59. [2016-12-01 16:16:28,986: WARNING/Worker-1] 28
  60.  
  61. [2016-12-01 16:16:29,987: WARNING/Worker-1] 29
  62.  
  63. [2016-12-01 16:16:30,990: INFO/MainProcess] Task app.tasks.add[06a8d603-a7d3-4732-b8f3-ad010d531200] succeeded in 30.049149203s: 12

celery学习笔记2的更多相关文章

  1. celery 学习笔记 01-介绍

    celery 学习笔记 01-介绍 celery 是 python 中的常用的任务队列框架,经常用于异步调用.后台任务等工作.celery 本身以 python 写,但协议可在不同的语言中实现,其它语 ...

  2. celery学习笔记1

    生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类.函数.线程.进程等).产生数据的模块,就形象地称为生产 ...

  3. Celery学习笔记

    转载请注明出处:点我 我的第一篇博客!嘿嘿! 在公司实习,接触到的第一个项目就用到了Celery,之前是完全没有接触过Celery这玩意,然后花了点时间仔细的研究了下怎么用.在学习过程中也遇到了些问题 ...

  4. Swift学习笔记一

    最近计划把Swift语言系统学习一下,然后将MagViewer用这种新语言重构一次,并且优化一下,这里记录一下Swift的学习笔记. Swift和Objective-C相比,在语法和书写形式上做了很多 ...

  5. Knockout.js快速学习笔记

    原创纯手写快速学习笔记(对官方文档的二手理解),更推荐有时间的话读官方文档 框架简介(Knockout版本:3.4.1 ) Knockout(以下简称KO)是一个MVVM(Model-View-Vie ...

  6. 【目录】Python学习笔记

    目录:Python学习笔记 目标:坚持每天学习,每周一篇博文 1. Python学习笔记 - day1 - 概述及安装 2.Python学习笔记 - day2 - PyCharm的基本使用 3.Pyt ...

  7. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  8. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  9. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

随机推荐

  1. MongoDB之整库备份还原单表collection备份还原

    MongoDB之整库备份还原单表collection备份还原 cd D:\MongoDB\bin 1整库备份: mongodump -h dbhost -d dbname -o dbdirectory ...

  2. SharePoint 列表项通过自定义WebService读取

    简述:给其他系统提供集成,发现SharePoint自带的WebService各种不好使,索性就自己写一点,也当做自己学习的记录了.当然内容比较简单,希望大侠们不要介意,也不要骂我啊.好了,进入正题吧. ...

  3. STM32中GPIO的8种工作模式

    一.推挽输出:可以输出高.低电平,连接数字器件:推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止.高低电平由IC的电源决定.形象点解释:推挽,就是有推有拉,任何 ...

  4. Xcode使用心得02:如何在项目中关闭ARC特性

    在obj-c系列内存管理的博文里大家应该对ARC有所了解,一般是不推荐关闭ARC特性的,但你也保不齐啥时候有这个需求,于是乎我们看看在最新的x6b中如何将其关闭吧. 因为Build Seting里的子 ...

  5. Jmeter(二十五)_Xpath关联

    在Jmeter中,除了正则表达式可以用作关联,还有一种方式也可以做关联,那就是 XPath Extractor.它是利用xpath提取出关键信息,传递变量. 具体用法 添加一个后置处理器-XPath ...

  6. RHEL7.0 Docker离线安装以及实战笔记

    1.概述 最近在琢磨一个事--在RHEL 7.0系统上离线安装使用Docker.然后配置JAVAEE环境,发布Web服务.在网上查了资料,大多数是在线安装的,其他的要么是环境不同,要么资料包找不到了. ...

  7. 简单poi创建execl

    Workbook workbook = new HSSFWorkbook();// 创建一个Excel文件 Workbook workbook = new XSSFWorkbook();// 创建一个 ...

  8. VMware虚拟化培训手册

    一.VMware虚拟化架构概述 1.1VMware虚拟化架构图 如上图所示,虚拟化由物理主机(即ESXI主机).虚拟化管理程序(vCenter Server).虚拟机(操作系统).存储等基本组成. 1 ...

  9. jBPM4工作流应用开发指南

    首先十分感谢作者给我这个机会在他的作品即将问世之前做一些感想,也正好让我能在忙碌中抽空回顾一下这么多年在技术平台方面走过的路以及在Workflow方面的点点滴滴.因为本书是介绍jBPM的专业书籍,所以 ...

  10. 前端mv框架下(目前写的是vue),对组件抽象的思考

    前沿: 抽象是门大学问.前端mv框架中,以组件化的概念为主.经常会考虑抽象到组件级别,进行复用.合理的抽象,能提高效率,减少业务逻辑视图的耦合程度.不合理的抽象,则会增加代码的复杂程度. 遇到的问题 ...