python---Celery分布式任务队列了解
linux下定时器了解
Celery 框架学习笔记(不错哟)
Celery 分布式任务队列快速入门
Celery的最佳实践
一、Celery介绍
Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, 举几个实例场景中可用的例子:
- 你想对100台机器执行一条批量命令,可能会花很长时间 ,但你不想让你的程序等着结果返回,而是给你返回 一个任务ID,你过一段时间只需要拿着这个任务id就可以拿到任务执行结果, 在任务执行ing进行时,你可以继续做其它的事情。
- 你想做一个定时任务,比如每天检测一下你们所有客户的资料,如果发现今天 是客户的生日,就给他发个短信祝福
Celery 在执行任务时需要通过一个消息中间件来接收和发送任务消息,以及存储任务结果, 一般使用rabbitMQ or Redis。所以我们需要先去安装这个软件。
Celery的构架
Celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。
消息中间件
Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成,包括,RabbitMQ,Redis,MongoDB等,这里我先去了解RabbitMQ,Redis。
任务执行单元
Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中
任务结果存储
Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括Redis,MongoDB,Django ORM,AMQP等,这里我先不去看它是如何存储的,就先选用Redis来存储任务执行结果。
一般通过启动一个或多个worker进程来部署Celery。
这些worker进程连接上消息代理(以下称之为broker)来获取任务请求。
broker随机将任务请求分发给worker。
通过调用Celery的API,用户生成一个任务请求,并且将这个请求发布给broker。
在worker完成任务后,将完成的任务信息发送给result store(设置的backend),从中获取信息。
通过启动新的worker进程并让这些进程连上broker,可以很方便的扩展worker池。
每个worker可以和其他的worker同步执行任务。
优点:
简单:一单熟悉了celery的工作流程后,配置和使用还是比较简单的
高可用:当任务执行失败或执行过程中发生连接中断,celery 会自动尝试重新执行任务
快速:一个单进程的celery每分钟可处理上百万个任务
灵活: 几乎celery的各个组件都可以被扩展及自定制
安装:
pip3 install celery
二:基本使用(windows下即可)
(一)创建一个任务文件cel.py
from celery import Celery app = Celery('tasks',
broker='redis://127.0.0.1', #这里面存放任务,worker去里面获取任务,将执行结果放入backend中 注意:由于我们安装的redis配置为本机监听,所以使用127.0.0.1才可,若是使用localhost可能无法连接
backend='redis://127.0.0.1') #从这里面获取我们任务执行的结果 @app.task
def add(x, y):
print("running...", x, y)
return x + y @app.task
def cmd(comm):
print(comm)
return comm
(二)启动Celery Worker来开始监听并执行任务
注意:在windows下可能使用会报错
解决方案:
1.安装eventlet
pip install eventlet
2.启动时加上一个参数
celery -A <任务文件> worker -l info -P eventlet
开始使用
1.启动Celery Worker来开始监听并执行任务
celery -A cel worker -l info -P eventlet
2.在python命令行中连接celery,调用任务
D:\MyPython\day25\twisted_test>python
Python 3.5. (v3.5.4:3f56838, Aug , ::) [MSC v. bit (AMD64
on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from cel import add,cmd
>>> t = add.delay(,)
>>> t.get()
(三)设置超时处理
from celery import Celery
import time app = Celery('tasks',
broker='redis://127.0.0.1',
backend='redis://127.0.0.1') @app.task
def add(x, y):
print("running...", x, y)
return x + y @app.task
def cmd(comm):
time.sleep(10)
return comm
再次启用:
>>> c = cmd.delay("ccc")
>>> c.get() #会等待到10秒才会获取到值
'ccc'
[-- ::,: INFO/MainProcess] Task cel.cmd[ff9379e7-520e-41c2-ac1d
-79400e042fb8] succeeded in .014999999999418s: 'ccc' #会一直等待10秒才会返回给get
我们需要设置超时时间:
>>> c.get(timeout=1) #我们将任务delay交给远程后,远程已经开始执行了,不过当我们调用get时远程还是没有执行完毕而已
Traceback (most recent call last):
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-p
ackages\celery\backends\async.py", line 255, in _wait_for_pending
on_interval=on_interval):
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-p
ackages\celery\backends\async.py", line 54, in drain_events_until
raise socket.timeout()
socket.timeout During handling of the above exception, another exception occurred: Traceback (most recent call last):
File "<stdin>", line , in <module>
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-p
ackages\celery\result.py", line 224, in get
on_message=on_message,
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-p
ackages\celery\backends\async.py", line 188, in wait_for_pending
for _ in self._wait_for_pending(result, **kwargs):
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-p
ackages\celery\backends\async.py", line 259, in _wait_for_pending
raise TimeoutError('The operation timed out.')
celery.exceptions.TimeoutError: The operation timed out.
我们要么捕获错误,要么使用其他方法ready,去查看远程执行状态,False未完成,True已完成
>>> c = cmd.delay("cccde")
>>> c.ready()
False
>>> c.ready()
False
>>> c.ready()
False
>>> c.ready()
True
>>> c.get()
'cccde'
(四)其他命令
1.开启多个worker在后台
celery multi start w1 -A proj -l info
2.重启
celery multi restart w1 -A proj -l info
3.停止
celery multi stop w1 -A proj -l info
4.等待任务执行完毕后停止
celery multi stopwait w1 -A proj -l info
三:项目中使用celery(常与Django一起)
项目目录:
celProject 目录
---celery.py #这个文件必须这样命名
---tasks.py
---tasks2.py
from __future__ import absolute_import, unicode_literals #是说下面的celery是python安装包决定路径引入,而不是当前项目
from celery import Celery #celery是指python安装包决定路径引入,.celery是当前目录引入 app = Celery('proj', #celery APP名称
broker='redis://127.0.0.1',
backend='redis://127.0.0.1',
include=['celProject.tasks','celProject.tasks2']) #include引入的是当前项目下的任务,为列表,可以引入多个 # Optional configuration, see the application user guide.
app.conf.update( #设置配置
result_expires=, #设置结果缓存时间
) if __name__ == '__main__':
app.start()
celery.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 @app.task
def xsum(numbers):
return sum(numbers)
tasks.py
from __future__ import absolute_import, unicode_literals
from .celery import app #用到他的装饰器 @app.task
def cmd(comm):
print("running cmd...")
return comm @app.task
def file_transfer(filename):
print("send file")
tasks2.py
命令执行:启动Celery Worker和python解释器都是在项目同级下进行的
celery -A celProject worker -l info -P eventlet
>>> from celProject import tasks,tasks2
>>> t2 = tasks2.cmd.delay('ff')
>>> t2.get()
'ff'
>>> t2 = tasks.xsum.delay([,,,])
>>> t2.get()
四:设置定时器(定时执行任务)流程图中celery beat(任务调度器)
我们另起一个进程,执行任务调度器
celery -A 项目.具体任务 beat #启动任务调度器
任务调度器,内部相当于,一直循环计时,每当时间一到,将放置一个任务到broker中间件中,任务就可以由worker执行
接着在上面的项目目录下创建一个任务:ontime_task.py
celProject 目录
---celery.py #这个文件必须这样命名
---tasks.py
---tasks2.py
---ontime_task.py #任务调度器
from __future__ import absolute_import, unicode_literals
from celery.schedules import crontab
from .celery import app @app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
# Calls test('hello') every seconds.
sender.add_periodic_task(10.0, test.s('hello'), name='add every 10') #.s就是相当于delay,发送到worker执行 # Calls test('world') every seconds
sender.add_periodic_task(30.0, test.s('world'), expires=) #默认是秒单位 # Executes every Monday morning at : a.m.
sender.add_periodic_task(
crontab(hour=7, minute=30, day_of_week=1), #可以通过crontab设置其他格式时间
test.s('Happy Mondays!'),
) @app.task
def test(arg): #定时执行的任务
print(arg)
正常启动Celery Worker,然后开启任务调度器
celery -A celProject worker -l info -P eventlet #开启一个worker,一会任务调度器中任务由他执行
celery -A celProject.ontime_task beat -l debug #开启任务调度器,由于我们是同项目中app,所以我们需要在项目同级下启动该任务
测试效果:每隔10秒一个hello,30秒一个world...
补充:上面是函数形式执行的定时任务,下面使用配置文件模式
修改ontime_task.py
from __future__ import absolute_import, unicode_literals
from celery.schedules import crontab
from .celery import app app.conf.beat_schedule = {
'add-every-monday-morning': {
'task': 'celProject.tasks.add', #这里的任务名,我们需要和启动的worker显示的任务列表中任务一致
'schedule': crontab(hour=, minute=, day_of_week=),
'args': (, ),
},
'add-every-5-seconds': {
'task': 'celProject.tasks.add', # 这里的任务名,我们需要和启动的worker显示的任务列表中任务一致
'schedule': ,
'args': (, ),
},
'add-every-10-seconds': {
'task': 'celProject.tasks.mul', # 这里的任务名,我们需要和启动的worker显示的任务列表中任务一致
'schedule': ,
'args': (, ),
},
} app.conf.timezone = "UTC" @app.task
def test(arg):
print(arg)
重新启动任务调度器,测试结果
五:与Django联合使用
(一)在Django项目中创建任务
1.在项目配置文件同级下设置celery.py文件,功能和上面一样,负责收集任务,进行调度
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery # set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CRM.settings') #需要和项目名一致 app = Celery('CRM') #这个是设置worker名称,随便写,与项目一致吧 # Using a string here means the worker don't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY') # Load task modules from all registered Django app configs.
app.autodiscover_tasks() @app.task(bind=True)
def debug_task(self): #测试任务,可以不要
print('Request: {0!r}'.format(self.request))
2.在各个所需要定时任务的APP下添加tasks.py文件
from __future__ import absolute_import, unicode_literals
from celery import shared_task @shared_task
def add(x, y):
return x + y @shared_task
def mul(x, y):
return x * y @shared_task
def xsum(numbers):
return sum(numbers)
sale下的tasks.py
from __future__ import absolute_import, unicode_literals
from celery import shared_task @shared_task
def cmd(comm):
print("running cmd...")
return comm @shared_task
def file_transfer(filename):
print("send file")
student下的tasks.py
任务创建完毕。
3.可以先在项目下开启worker
celery -A CRM worker -l info -P eventlet #是在settings.py文件的上级目录的同级去执行的启动命令,因为celery放在这个目录下面
(二)开始配置Django
1. 由于需要使用到django-celery-beat模块,所以需要先安装
pip install django-celery-beat
2.添加django-celery-beat模块到INSTALLED_APPS中,便于操作数据库
INSTALLED_APPS = (
...,
'django_celery_beat',
)
3.配置数据库
python manage.py migrate
4.启动项目,在管理员页面生成任务
(1)查看表
(2)设置周期:固定时间和间隔时间两种
(3)创建任务
5.启动任务调度器,会去数据库中获取我们设置的任务,按照我们设置的时间间隔执行任务
celery -A CRM beat -l info -S django #也是需要在settings的上级目录下执行
(三)结果查看
python---Celery分布式任务队列了解的更多相关文章
- Celery 分布式任务队列快速入门
Celery 分布式任务队列快速入门 本节内容 Celery介绍和基本使用 在项目中如何使用celery 启用多个workers Celery 定时任务 与django结合 通过django配置cel ...
- Celery 分布式任务队列快速入门 以及在Django中动态添加定时任务
Celery 分布式任务队列快速入门 以及在Django中动态添加定时任务 转自 金角大王 http://www.cnblogs.com/alex3714/articles/6351797.html ...
- 【转】Celery 分布式任务队列快速入门
Celery 分布式任务队列快速入门 本节内容 Celery介绍和基本使用 在项目中如何使用celery 启用多个workers Celery 分布式 Celery 定时任务 与django结合 通过 ...
- day21 git & github + Celery 分布式任务队列
参考博客: git & github 快速入门http://www.cnblogs.com/alex3714/articles/5930846.html git@github.com:liyo ...
- 【Python】分布式任务队列Celery使用参考资料
Python-Celery Homepage | Celery: Distributed Task Queue User Guide - Celery 4.0.2 documentation Task ...
- celery --分布式任务队列
一.介绍 celery是一个基于python开发的分布式异步消息任务队列,用于处理大量消息,同时为操作提供维护此类系统所需的工具. 它是一个任务队列,专注于实时处理,同时还支持任务调度.如果你的业务场 ...
- Celery -- 分布式任务队列 及实例
Celery 使用场景及实例 Celery介绍和基本使用 在项目中如何使用celery 启用多个workers Celery 定时任务 与django结合 通过django配置celery perio ...
- Celery 分布式任务队列入门
一.Celery介绍和基本使用 Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery ...
- celery分布式任务队列的使用
一.Celery介绍和基本使用 Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery ...
- Celery分布式任务队列快速入门
本节内容 1. Celery介绍和基本使用 2. 项目中使用Celery 3. Celery定时任务 4. Celery与Django结合 5. Django中使用计划任务 一 Celery介绍和基 ...
随机推荐
- xpath抓取的值有\r\n\t时,去掉的方法
解决办法: normalize-space() 例子: 原来的xpath为: user=selector.xpath('//*[@id="Con"]/tr[1]/th/text() ...
- 作业要求20181113-4 Beta阶段第1周/共2周 Scrum立会报告+燃尽图 02
作业要求:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2384 版本控制:[https://git.coding.net/lglr201 ...
- excel导出功能原型
本篇博客是记录自己实现的excel导出功能原型,下面我将简单介绍本原型: 这是我自制的窗体,有一个ListView和一个Button(导出)控件. 这是我在网上找到了使用exel需要引用的库. usi ...
- 自我介绍for软件工程课程
石家庄铁道大学学生,正在学习软件工程课程. 对于软件工程课程,没什么太大的希望.度了一下,发现软件工程课程近年来比较脱节,这次用新课本不知道效果怎么样.嗯,等课本到手看看再说吧. 自己的目标:我希望能 ...
- OpenCV学习笔记——腐蚀与膨胀
1.膨胀 此操作将图像 与任意形状的内核 (),通常为正方形或圆形,进行卷积. 内核 有一个可定义的 锚点, 通常定义为内核中心点. 进行膨胀操作时,将内核 划过图像,将内核 覆盖区域的最大相素值提取 ...
- 软工实践 - 第三十次作业 Beta答辩总结
福大软工 · 第十二次作业 - Beta答辩总结 组长本次博客作业链接 项目宣传视频链接 本组成员 1 . 队长:白晨曦 031602101 2 . 队员:蔡子阳 031602102 3 . 队员:陈 ...
- ASP.NET Core 中的 Razor 页面介绍
标题:ASP.NET Core 中的 Razor 页面介绍 地址:https://docs.microsoft.com/zh-cn/aspnet/core/razor-pages/index?view ...
- lintcode-413-反转整数
413-反转整数 将一个整数中的数字进行颠倒,当颠倒后的整数溢出时,返回 0 (标记为 32 位整数). 样例 给定 x = 123,返回 321 给定 x = -123,返回 -321 标签 整数 ...
- Java容器深入浅出之String、StringBuffer、StringBuilder
对字符串的花式处理一直是现代应用系统的主要操作之一,也是对Java基础知识考察的重要方面.事实上,Java字符串类的底层是通过数组来实现的.具体来说,String类是固定长度的数组,StringBuf ...
- Delphi中的DBGrid控件
在Delphi中,DBGrid控件是一个开发数据库软件不能不使用的控件,其功能非常强大,可以配合SQL语句实现几乎所有数据报表的显示,操作也非常简单,属性.过程.事件等都非常直观,但是使用中,有时侯还 ...