本节内容

1. Celery介绍和基本使用

2. 项目中使用Celery

3. Celery定时任务

4. Celery与Django结合

5. Django中使用计划任务

一  Celery介绍和基本使用

需求场景

1.  对100台命令执行一条批量命令,命令执行需要很长时间,但是不想让主程序等着结果返回,而是给主程序返回一个任务ID,task_id

主程序过一段时间根据task_id,获取执行结果即可,再命令执行期间,主程序 可以继续做其他事情

2.  定时任务,比如每天检测一下所有的客户资料,发现是客户的生日,发个祝福短信

解决方案

1.  逻辑view 中启一个进程

父进程结束,子进程跟着结束,子进程任务没有完成,不符合需求

父进程结束,等着子进程结束,父进程需等着结果返回,不符合需求

小结:该方案解决不了阻塞问题,即需要等待

2. 启动 subprocess,任务托管给操作系统执行

实现task_id,实现异步,解决阻塞

小结:大批量高并发,主服务器会出现问题,解决不了并发

3. celery

celery提供多子节点,解决并发问题

celery介绍

celery是一个基于python开发的分布式异步消息队列,轻松实现任务的异步处理

celery在执行任务时需要一个消息中间件来接收和发送任务消息,以及存储任务结果,一般使用RabbitMQ 或 Redis

celery优点

简单:熟悉celery的工作流程后,配置使用简单

高可用:当任务执行失败或执行过程中发生连接中断,celery会自动尝试重新执行任务

快速:一个单进程的celery每分钟可处理上百万个任务

灵活:几乎celery的各个组件都可以被扩展及自定制

celery基本工作流程

其中中间队列用于分配任务以及存储执行结果

celery安装及使用

1.  安装python模块

pip3 install celery
pip3 install redis

2.  安装redis服务

wget  http://download.redis.io/releases/redis-3.2.8.tar.gz
tar -zxvf redis-3.2.8.tar.gz
cd redis-3.2.8
make src/redis-server # 启动redis 服务

3.  创建一个celery application 用来定义任务列表

创建一个任务 tasks.py

from celery import Celery

app = Celery('TASK',
broker='redis://localhost',
backend='redis://localhost') @app.task
def add(x,y):
print("running...",x,y)
return x+y

4.  启动celery worker 来开始监听并执行任务

celery -A tasks worker --loglevel=info

tasks 任务文件名,worker 任务角色,--loglevel=info 任务日志级别

5.  调用任务

打开另外终端,进入命令行模式,调用任务

6.  celery常用接口

  • tasks.add(4,6) ---> 本地执行

  • tasks.add.delay(3,4) --> worker执行

  • t=tasks.add.delay(3,4)  --> t.get()  获取结果,或卡住,阻塞

  • t.ready()---> False:未执行完,True:已执行完

  • t.get(propagate=False) 抛出简单异常,但程序不会停止

  • t.traceback 追踪完整异常

补充:如何使用第三方工具

1. 导入第三方包,如 from celery import Celery

2. 实例化第三方类,如 app = Celery(......)

3. 实例化的对象去关联执行任务的方法,如 @app.task

4. 分区角色  worker 执行任务,broker分配任务

二  项目中使用Celery

1.  项目目录结构

project
|-- __init__.py
|-- celery.py # 配置文档
|-- tasks.py # 任务函数
|-- tasks2.py # 任务函数

2.  项目文件

project/celery.py

# from celery import Celery 默认当前路径,更改为绝对路径(当前路径有个celery.py文件啦)
from __future__ import absolute_import, unicode_literals
from celery import Celery app = Celery('project',
broker='redis://localhost',
backend='redis://localhost',
include=['project.tasks','project.tasks2']) # 配置文件和任务文件分开了,可以写多个任务文件 # app 扩展配置
app.conf.update(
result_expires=3600,
) if __name__ == '__main__':
app.start()

celery.py作用相当于配置文件

project/tasks.py

from __future__ import absolute_import, unicode_literals
from .celery import app @app.task
def add(x, y):
return x + y @app.task
def mul(x, y):
return x * y

project/tasks.py

from __future__ import absolute_import, unicode_literals
from .celery import app @app.task
def hello():
return 'Hello World'

3.  启动项目worker

celery -A project worker -l info

其中 project 为项目名

另启终端,与project同目录进入python3

4.  实现分布式 
当启动多个时 celery -A project worker -l info,去broker去相应任务,实现分布式
 
 
5.  后台启动woker
celery multi start w1 -A project -l info
celery multi start w2 -A project -l info
celery multi start w3 -A project -l info celery multi restart w1 -A project -l info
celery multi stop w1 w2 w3 # 任务立刻停止
celery multi stopwait w1 w2 w3 # 任务执行完,停止

 
三  Celery定时任务
 
 
 
celery支持定时任务,设定好任务的执行时间,celery就会定时帮你执行,这个定时任务模块叫 celery beat
 
项目目录结构
project
|-- __init__.py
|-- celery.py # 配置文件
|-- periodic_task.py # 定时任务文件

脚本celery.py

from __future__ import absolute_import, unicode_literals
from celery import Celery app = Celery('project',
broker='redis://localhost',
backend='redis://localhost',
include=['project.periodic_task',]) app.conf.update(
result_expires=3600,
) if __name__ == '__main__':
app.start()

脚本periodic_task.py

from __future__ import absolute_import, unicode_literals
from .celery import app
from celery.schedules import crontab @app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
# 每10s调用 test('hello')
sender.add_periodic_task(10.0, test.s('hello'), name='add every 10') # 每20s调用 test('world')
sender.add_periodic_task(20.0, test.s('world'), expires=10) # 每周一早上7:30 执行 test('Happy Mondays!')
sender.add_periodic_task(
crontab(hour=7, minute=30, day_of_week=1), # 可灵活修改
test.s('Happy Mondays!'),
) @app.task
def test(arg):
print(arg)
 
启动角色 worker  执行任务
celery -A project worker -l info
启动角色 beat 将定时任务放到队列中
celery -A  project.periodic_task  beat  -l  debug

也可以在配置文件celery.py 里添加定时任务

app.conf.beat_schedule = {
'add-every-30-seconds': {
'task': 'project.tasks.add',
'schedule': 30.0,
'args': (16, 16)
},
}
app.conf.timezone = 'UTC'

每周1的早上7.30执行project.tasks.add任务

 

还有更多定时配置方式如下:

Example Meaning
crontab() 每分钟执行  
crontab(minute=0,hour=0) 每天0点执行
crontab(minute=0,hour='*/3') 每3小时执行: midnight, 3am, 6am, 9am, noon, 3pm, 6pm, 9pm.
crontab(minute=0,hour='0,3,6,9,12,15,18,21')
同上
crontab(minute='*/15') 每15分钟执行
crontab(day_of_week='sunday') 周天的每分钟执行
crontab(minute='*',hour='*',day_of_week='sun')
同上
crontab(minute='*/10',hour='3,17,22',day_of_week='thu,fri')

周三、五,3-4 am, 5-6 pm, and 10-11 pm,每10分钟执行

crontab(minute=0,hour='*/2,*/3') 每小时/2和每小时/3,执行
crontab(minute=0, hour='*/5') 每小时/5,执行
crontab(minute=0, hour='*/3,8-17') 每小时/3,8am-5pm,执行
crontab(0,0,day_of_month='2') Execute on the second day of every month.
crontab(0,0,day_of_month='2-30/3')
Execute on every even numbered day.
crontab(0,0,day_of_month='1-7,15-21')
Execute on the first and third weeks of the month.
crontab(0,0,day_of_month='11',month_of_year='5')
Execute on the eleventh of May every year.
crontab(0,0,month_of_year='*/3')
Execute on the first month of every quarter.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
四  Celery与Django结合
 
 
 
1.  项目目录结构
LearnCelery
|-- app1
|-- tasks.py
|-- models.py
|-- app2
|-- tasks.py
|-- models.py
|-- LearnCelery
|-- __init__.py
|-- celery.py
|-- settings.py

2.  脚本代码

LearnCelery/app/tasks.py   # 必须叫这个名字

from __future__ import absolute_import, unicode_literals
from celery import shared_task
import time # 所有的app都可以调用
@shared_task
def add(x, y):
time.sleep(10)
return x + y @shared_task
def mul(x, y):
time.sleep(10)
return x * y

LearnCelery/LearnCelery/__init__.py

from __future__ import absolute_import, unicode_literals

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app __all__ = ['celery_app']

LearnCelery/LearnCelery/celery.py

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery # 单独脚本调用Django内容时,需配置脚本的环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings') app = Celery('mysite') # CELERY_ 作为前缀,在settings中写配置
app.config_from_object('django.conf:settings', namespace='CELERY') # 到Django各个app下,自动发现tasks.py 任务脚本
app.autodiscover_tasks() @app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))

LearnCelery/LearnCelery/settings.py

# For celery
CELERY_BROKER_URL = 'redis://localhost'
CELERY_RESULT_BACKEND = 'redis://localhost'

3.  启动celery

celery -A LearnCelery worker -l debug
4.  urls.py 视图处理
urlpatterns = [
url(r'^celery_call/$', views.celery_call),
url(r'^celery_res/$', views.celery_res),
]
五  Django中使用计划任务
 
 
1.  安装插件
pip3 install django-celery-beat
2.  修改配置 settings.py
INSTALLED_APPS = [
....
'django_celery_beat',
]

3. 数据库迁移

python manage.py migrate

4.  启动 celery beat

celery -A LearnCelery beat -l info -S django

定时任务存到数据库里,启动beat定时取任务放到队列里执行

5.  admin管理

 

启动celery beat和worker,会发现每隔2秒,beat会发起一个任务消息让worker执行tasks任务

注意,经测试,每添加或修改一个任务,celery beat都需要重启一次,要不然新的配置不会被celery beat进程读到

 
更多信息请参考
http://www.cnblogs.com/alex3714/articles/6351797.html
 
代码示例请参考
https://github.com/Jonathan1314/LearnCelery 
 

Celery分布式任务队列快速入门的更多相关文章

  1. Celery 分布式任务队列快速入门

    Celery 分布式任务队列快速入门 本节内容 Celery介绍和基本使用 在项目中如何使用celery 启用多个workers Celery 定时任务 与django结合 通过django配置cel ...

  2. Celery 分布式任务队列快速入门 以及在Django中动态添加定时任务

    Celery 分布式任务队列快速入门 以及在Django中动态添加定时任务 转自 金角大王 http://www.cnblogs.com/alex3714/articles/6351797.html ...

  3. 【转】Celery 分布式任务队列快速入门

    Celery 分布式任务队列快速入门 本节内容 Celery介绍和基本使用 在项目中如何使用celery 启用多个workers Celery 分布式 Celery 定时任务 与django结合 通过 ...

  4. day21 git & github + Celery 分布式任务队列

    参考博客: git & github 快速入门http://www.cnblogs.com/alex3714/articles/5930846.html git@github.com:liyo ...

  5. Celery ---- 分布式队列神器 ---- 入门

    原文:http://python.jobbole.com/87238/ 参考:https://zhuanlan.zhihu.com/p/22304455 Celery 是什么? Celery 是一个由 ...

  6. Celery 分布式任务队列入门

    一.Celery介绍和基本使用 Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery ...

  7. celery --分布式任务队列

    一.介绍 celery是一个基于python开发的分布式异步消息任务队列,用于处理大量消息,同时为操作提供维护此类系统所需的工具. 它是一个任务队列,专注于实时处理,同时还支持任务调度.如果你的业务场 ...

  8. Celery -- 分布式任务队列 及实例

    Celery 使用场景及实例 Celery介绍和基本使用 在项目中如何使用celery 启用多个workers Celery 定时任务 与django结合 通过django配置celery perio ...

  9. celery分布式任务队列的使用

    一.Celery介绍和基本使用 Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery ...

随机推荐

  1. Creating adaptive web recommendation system based on user behavior(设计基于用户行为数据的适应性网络推荐系统)

    文章介绍了一个基于用户行为数据的推荐系统的实现步骤和方法.系统的核心是专家系统,它会根据一定的策略计算所有物品的相关度,并且将相关度最高的物品序列推送给用户.计算相关度的策略分为两部分,第一部分是针对 ...

  2. windows注册表解析说明

    https://www.cnblogs.com/wfq9330/p/9176654.html

  3. kettle 无法正常启动问题

    Java环境配置后,双击spoon.bat无法打开 修改spoon.bat里内存配置: if "%PENTAHO_DI_JAVA_OPTIONS%"=="" s ...

  4. oracle 11g密码过期问题解决方法

    ORACLE 11G密码过期问题: 1.使用oracle用户进入sql编辑器中执行修改密码(原始密码,保持不变)的命令 sql>alter user 用户名 identified by &quo ...

  5. SSM商城项目(四)

    1. 学习计划 1.图片服务器 2.图片服务器安装 3.图片服务器的使用 4.图片上传功能 5.富文本编辑器的使用方法 6.商品添加功能实现 2. 图片服务器 1.存储空间可扩展. 2.提供一个统一的 ...

  6. Xshell 6安装与使用教程

    随着xshell5出现评估期已过的问题,发现好多人不知道怎么下载免费版的Xshell,在这里我将详细告诉大家如何下载和安装最新的Xshell6远程管理工具. Xshell安装 1.进入xshell英文 ...

  7. 2018面向对象程序设计(Java)第18周学习指导及要求

    2018面向对象程序设计(Java) 第18周学习指导及要求(2018.12.27-2018.12.30)   学习目标 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设 ...

  8. db2常见命令

    增加db2top命令的refresh间隔,默认值为2秒,下面的命令就可以每10秒刷新一次: $ db2top -i 10 -d sample 数据库本身太繁忙(dynamic SQL过多).建议增加 ...

  9. Rifidi

    简介 Rifidi是RFID软件公司Pramari推出了一款开源中间件平台,其主页是:http://www.rifidi.org/ 其分为Edge Server, Workbench, Prototy ...

  10. Iris数据集实战

    本次主要围绕Iris数据集进行一个简单的数据分析, 另外在数据的可视化部分进行了重点介绍. 环境 win8, python3.7, jupyter notebook 目录 1. 项目背景 2. 数据概 ...