celery_1:简介及定时任务简单使用
目录:
一、celery简介
二、基本概念
三、使用 Celery 实现异步任务的步骤
四、使用 Celery 实现定时任务的步骤
五、celery定时任务简单使用
一、celery:
1、定义:一个强大的分布式任务队列
2、作用:可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行(分布式)
3、应用场景:
(1)异步任务( async task ):发送邮件、或者文件上传, 图像处理等等一些比较耗时的操作
(2)定时任务( crontab ):在特定时间执行的任务
4、架构组成:
二、基本概念:
1、任务队列 / celery:
任务队列是一种跨线程、跨机器工作的一种机制.
任务队列中包含称作任务的工作单元。有专门的工作进程持续不断的监视任务队列,并从中获得新的任务并处理.其构成如上图所示。
2、任务模块:
包含异步任务和定时任务。其中,异步任务(async task)通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat进程周期性地将任务发往任务队列。
在定时任务中,celery beat:任务调度器。beat进程会读取配置文件里的内容(celerybeat_schedule里设置),周期性的将配置中到期需要执行的任务发送到任务队列。
3、消息中间件 Broker:
Broker ,即为任务调度队列,接收任务生产者发来的消息(即任务),将任务存入队列。 Celery 本身不提供队列服务,官方推荐使用 RabbitMQ 和 Redis 等。
4、任务执行单元 Worker:
Worker 是执行任务的处理单元,它实时监控消息队列,获取队列中调度的任务,并执行它。
5、任务结果存储 Backend:
Backend 用于存储任务的执行结果,以供查询。同消息中间件一样,存储也可使用 RabbitMQ, Redis 和 MongoDB 等
三、使用 Celery 实现异步任务的步骤:
(1) 创建一个 Celery 实例
(2) 启动 Celery Worker ,通过delay() 或 apply_async()(delay 方法封装了 apply_async, apply_async支持更多的参数 ) 将任务发布到broker
(3) 应用程序调用异步任务
(4)存储结果 (发布的任务需要return才会有结果,否则为空)
四、使用 Celery 实现定时任务的步骤:
Celery Beat:任务调度器,Beat进程会读取配置文件的内容,周期性地将配置中到期需要执行的任务发送给任务队列
(1) 创建一个 Celery 实例
(2) 配置文件中配置任务 ,发布任务 celery A xxx beat
(3) 启动 Celery Worker
(4) 存储结果
五、定时任务命令:
1、定时方式:
from celery.schedules import crontab from datetime import timedelta ...... 方式一: "schedule": timedelta(seconds=30), # hours=xx,minutes=xx 每小时/每分钟 (此项可以精确到秒)
# "schedule": crontab() # 与crontab的语法基本一致
# "schedule": crontab(minute="*/10", # 每十分钟执行
# "schedule": crontab(minute="*/1"), # 每分钟执行
# "schedule": crontab(minute=0, hour="*/1"), # 每小时执行
方式二: "schedule": crontab(minute="*/10"), # every 10 minutes
2、相关命令:
# 发布任务:celery -A 路径.celery_app beat
eg: celery -A celery_app.app beat
# 执行任务:celery -A 路径.celery_app worker
celery -A celery_app.app worker --loglevel=info
3、执行完毕后会在当前目录下产生一个二进制文件,celerybeat-schedule 。
该文件用于存放上次执行结果: 1、如果存在celerybeat-schedule文件,那么读取后根据上一次执行的时间,继续执行。 2、如果不存在celerybeat-schedule文件,那么会立即执行一次。 3、如果存在celerybeat-schedule文件,读取后,发现间隔时间已过,那么会立即执行。
六、celery定时任务简单使用
1、目录结构如下
celery_task
├── celeryconfig.py # celeryconfig配置文件
├── celery_app.py # celery对象
├── epp_scripts # 任务函数
│ ├── __init__.py
│ ├── test1.py
│ ├── test2.py
├── __init__.py
2、celery对象文件:celery.py
# coding:utf-8 # from __future__ import absolute_import # 拒绝隐式引入,因为celery.py的名字和celery的包名冲突,需要使用这条语句让程序正确地运行 from celery import Celery # 创建celery应用对象 app = Celery("celery_demo") # 导入celery的配置信息 app.config_from_object("celeryconfig")
3、celery配置文件:celeryconfig.py
from __future__ import absolute_import # 拒绝隐式引入,因为celery.py的名字和celery的包名冲突,需要使用这条语句让程序正确地运行 from celery.schedules import crontab from datetime import timedelta broker_url = "redis://127.0.0.1:6379/1" # 使用redis存储任务队列 result_backend = "redis://127.0.0.1:6379/2" # 使用redis存储结果 task_serializer = 'json' result_serializer = 'json' accept_content = ['json'] timezone = "Asia/Shanghai" # 时区设置 worker_hijack_root_logger = False # celery默认开启自己的日志,可关闭自定义日志,不关闭自定义日志输出为空 result_expires = 60 * 60 * 24 # 存储结果过期时间(默认1天) # 导入任务所在文件 imports = [ "epp_scripts.test1", # 导入py文件 "epp_scripts.test2", ] # 需要执行任务的配置 beat_schedule = { "test1": { "task": "epp_scripts.test1.celery_run", # 执行的函数 "schedule": timedelta(minutes=1), # every minute 每分钟执行 "args": () # # 任务函数参数 }, "test2": { "task": "epp_scripts.test2.celery_run", "schedule": timedelta(minutes=2), # every minute 每小时执行 "args": () }, }
3、任务函数:
# test1.py from celery_app import app def test11(): print("test11----------------") def test22(): print("test22--------------") test11() @app.task def celery_run(): test11() test22() if __name__ == '__main__': celery_run() # test2.py from celery_app import app def test33(): print("test33----------------") # print("------"*50) def test44(): print("test44--------------") # print("------" * 50) test33() @app.task def celery_run(): test33() test44() if __name__ == '__main__': celery_run()
4、发布任务:beat把任务发送到broker(这里broker用的是本地redis,记得要启动redis,默认队列名:celery,数据类型是list)
# 在celery_task目录下执行:celery -A celery_app.app beat
(venv) ➜ celery_task celery -A celery_app.app beat celery beat v5.0.5 (singularity) is starting. __ - ... __ - _ LocalTime -> 2021-01-14 17:50:18 Configuration -> . broker -> redis://127.0.0.1:6379/1 . loader -> celery.loaders.app.AppLoader . scheduler -> celery.beat.PersistentScheduler . db -> celerybeat-schedule . logfile -> [stderr]@%WARNING . maxinterval -> 5.00 minutes (300s)
5、查看消息中间件broker:
可以看到消息中间件redis中的默认消息队列celery,已经有2个任务
127.0.0.1:6379[1]> keys * 1) "_kombu.binding.celery" 2) "celery" 127.0.0.1:6379[1]> llen "celery" (integer) 2
6、启动worker执行任务:在celery_task目录下执行:celery -A celery_app.app worker --loglevel=info
(venv) ➜ celery_task celery -A celery_app.app worker --loglevel=info
-------------- celery@JS10226.local v5.0.5 (singularity) --- ***** ----- -- ******* ---- Darwin-17.7.0-x86_64-i386-64bit 2021-01-14 17:51:02 - *** --- * --- - ** ---------- [config] - ** ---------- .> app: celery_demo:0x106282810 - ** ---------- .> transport: redis://127.0.0.1:6379/1 - ** ---------- .> results: redis://127.0.0.1:6379/2 - *** --- * --- .> concurrency: 6 (prefork) -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) --- ***** ----- -------------- [queues] .> celery exchange=celery(direct) key=celery [tasks] . epp_scripts.test1.celery_run . epp_scripts.test2.celery_run [2021-01-14 17:51:02,904: INFO/MainProcess] Connected to redis://127.0.0.1:6379/1 [2021-01-14 17:51:02,911: INFO/MainProcess] mingle: searching for neighbors [2021-01-14 17:51:03,932: INFO/MainProcess] mingle: all alone [2021-01-14 17:51:03,953: INFO/MainProcess] celery@JS10226.local ready. [2021-01-14 17:51:04,096: INFO/MainProcess] Received task: epp_scripts.test2.celery_run[78071f3b-053f-45a9-a608-2db031396aa4] [2021-01-14 17:51:04,097: INFO/MainProcess] Received task: epp_scripts.test1.celery_run[08c64bb0-df09-4bd4-b53f-31727d2c503b] [2021-01-14 17:51:04,098: WARNING/ForkPoolWorker-4] test33---------------- [2021-01-14 17:51:04,098: WARNING/ForkPoolWorker-4] test44-------------- [2021-01-14 17:51:04,099: WARNING/ForkPoolWorker-4] test33---------------- [2021-01-14 17:51:04,099: WARNING/ForkPoolWorker-1] test11---------------- [2021-01-14 17:51:04,099: WARNING/ForkPoolWorker-1] test22-------------- [2021-01-14 17:51:04,099: WARNING/ForkPoolWorker-1] test11---------------- [2021-01-14 17:51:04,106: INFO/ForkPoolWorker-4] Task epp_scripts.test2.celery_run[78071f3b-053f-45a9-a608-2db031396aa4] succeeded in 0.008798735000000057s: None [2021-01-14 17:51:04,106: INFO/ForkPoolWorker-1] Task epp_scripts.test1.celery_run[08c64bb0-df09-4bd4-b53f-31727d2c503b] succeeded in 0.007856532999999999s: None