
运行 worker
celery -A proj worker -l info
运行 app
python managepy runserver 0000:8000
然后你打开浏览器的地址
输入刚才的账号密码就可以了。
项目中有使用到Celery框架,主要使用Celery来在使用Django搭建的项目中创建延时任务及周期任务。在使用过程中出现过延时任务及周期任务到预定时间未能执行的情况。Google、百度了一些网友的分析及解决方案,大多认为是Celery时区设置导致的问题。然而这些解答大多类似,而且并不能解决我心中的疑惑,因此决定研究源码一探究竟。
这里网上大多数解答存在问题的地方,将延时任务及周期任务混为一谈了。周期任务是存在一个周期,定时执行的任务,类似Linux系统的Crontab定时任务。而延时任务更类似一个普通的异步任务,不同的是存在一个ETA延时时间,这种任务只会执行一次。因此我们会分开讨论两种任务。
celery存在两个时区的配置 enable_utc 及 timezone ,前者表示是否使用UTC时间,后者表示celery使用的时区。celery默认使用UTC时间,若使用默认配置,则celery设置周期任务时,必须使用UTC时间,比如
当系统时间是北京时间时,这样的设置会导致这个任务并不会在每天北京时间9:30执行,而是17:30,因为UTC时间和北京时间相差8小时。因此这里我们将配置修改为
这样周期任务就能正常执行了
大多数网上的解答止步于上述的结果,认为上述设置之后,延时任务就同样没有任何问题了,其实不然,例如
我们准备让这个任务在 2021-08-19 18:10:30 去执行,结果呢
当requtc为True时,执行to_system_tz方法转换eta,否则直接使用Celery设置的时区转换,这个requtc又是什么?
从这里可以看出,当我们设置了args参数时,由hybrid_to_proto2返回,继续
omg!!!原来apply_async方法还有一个参数叫utc吗,而且默认值是True,看文档的时候并没有注意到!到这里,我们大概能看出问题的所在了,延时任务也可以认为普通的异步任务,存在自己的时区配置参数,之前提到的enable_utc并不能影响到这里。我们再看看传入的eta做了哪些处理。
传入的native类型的时间,居然直接被转换成UTC时间了!!!
讨论了这么多,我们能得出最终解决Celery时区问题的结论
1、对于周期任务,需要将celery的配置enable_utc设置成False,timezone设置成系统当前的时区
2、对于延时任务,如果需要设置eta,即精确在某一时间执行,则这个eta必须包含时区信息
最终结论相当简单,但是花了大量时间去研究了源码。对于延时任务eta设置曾经也是相当困惑,其实对于官方文档确实有提到,eta必须要包含时区信息,之前并没有注意到
任务队列是一个将工作分布到多线程或多台机器上的机制。
一个任务队列的输入是一个工作单元也被称为任务。专用的工作者进程将会持续监控任务队列并执行它们。
Celery通过消息进行通信,通常通过一个中间人在客户端和工作者之间协调。客户端初始化一个任务并将它加到任务队列,中间人将其发送到工作者。
一个Celery系统可以由多个工作者和中间人构成,这为高可用性和横向扩展提供了便利。
Celery是用python语言实现的,但是可以使用任何语言实现其协议。除了python以外,还有nodejs实现的node-celery和一个php实现的客户端。
node-celery for Nodejs, and a PHP client
不同语言之间可以相互 *** 作,通过使用webhooksusing webhooks
看到标题,相信大家就知道这个帖子要讲啥了……如果你希望在django中使用celery执行异步任务,用MQ(rabbimq,下同)做消息中间件,那么此贴完全可以满足你,包括celeryp、MQ配置,以及MQ路由配置等,相信你会喜欢。
简单说明一下:
1,django:web框架
2,celery: 用于创建执行异步任务
3,RabbitMQ:消息队列,主要用于消息存储
对于celery,rabbimq安装没啥好说的, pip直接装就好了,配置与启动也不赘述。关键环节简要说明如下:
一,在django中配置和使用celery
配置大致如下:
(1),工程目录下,创建celerypy, 内容编辑如下:
……
(2), 各app根目录下创建taskspy
app相关的task均放置在taskspy中,并用装饰器shared_task装饰,示例如下:
def get_jid_result(args, kwargs): pass 任务调度方法:
1)后台定时执行task,可安装djcelery模块,在django后台调度已注册的任务,关于djcelery的使用方法,在此不详细介绍。
2)触发调度,在需要调用task的d地方,直接调用各task的delay()方法即可(当然要先import),如:
get_jid_resultdelay(args, kwargs)
二, celery woker
工程目录下执行sudo -u apache bash -c 'celery -A patools worker -l info (注意,此处使用apache用户执行,celery建议不要使用superuser 启动),启动celery worker。
建议:为确保celery worker进程平稳运行, 可以使用superivsor守护该进程的执行, 配置示例如下:
进入supervisorctl, 启动相应进程,OK!
三,中间件rabbitmq
对于中间件的选择,redis,MQ都可以,差异不作详细说明,视应用情况而选择。实践中采用rabbimq作为中间件,在此,对rabbimq路由做简单说明。
django settings配置,如celery配置部分, 另外,配置消息路由:
CELERY_DEFAULT_QUEUE = 'default'CELERY_DEFAULT_EXCHANGE = 'default'
CELERY_DEFAULT_EXCHANGE_TYPE = 'direct'
CELERY_DEFAULT_ROUTING_KEY = 'default'# routing task
CELERY_IMPORTS = (
# 注册各应用tasks文件在此,注意,必须确保注册模块存在,否则将导致worker进程报错
"app1tasks",
"app2tasks",
# other apps
)
#交换器定义,示例如下:
# 路由定义, 示例如下:
以上是我在搭建基于Django框架的过程中对celery及MQ配置应用实践的小结,希望对有相关需求的同志们有些许的帮助,不足之处多多批评指正。
以上就是关于谁能帮我解答这个问题涉及到django,scrapy,celery全部的内容,包括:谁能帮我解答这个问题涉及到django,scrapy,celery、定时任务、如何用 Python 构建一个简单的分布式系统等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)