Celery

官方

  Celery 官网:http://www.celeryproject.org/

  Celery 官方文档英文版:http://docs.celeryproject.org/en/latest/index.html

  Celery 官方文档中文版:http://docs.jinkan.org/docs/celery/

  Celery是一个简单、灵活且可靠的,处理大量消息的分布式系统

  专注于实时处理的异步任务队列

  同时也支持任务调度

  Celery is a project with minimal funding, so we don’t support Microsoft Windows. Please don’t open any issues related to that platform.

Celery的主要作用

  异步任务:项目中同步的操作,可以通过celery把它做成异步

  延迟任:隔一会再执行任务

  定时任务:每隔多长时间干什么事

  注:如果你的项目仅仅想做定时任务,没有必要使用celery,使用apscheduler

大白话理解Celery

  1、可以不依赖任何服务器,通过自身命令,启动服务

  2、celery服务为为其他项目服务提供异步解决任务需求的

    注:会有两个服务同时运行,一个是项目服务(django),一个是celery服务,项目服务将需要异步处理的任务交给celery服务,celery就会在需要时异步完成项目的需求

Celery架构图

  Celery的架构由三部分组成,消息中间件(message broker)、任务执行单元(worker)和 任务执行结果存储(task result store)组成。

   消息中间件

   Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成。包括,RabbitMQ, Redis等等

  任务执行单元

  Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中。

  任务结果存储

  Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括AMQP, redis等

使用场景

  异步执行:解决耗时任务,将耗时操作任务提交给Celery去异步执行,比如发送短信/邮件、消息推送、音视频处理等等

  延迟执行:解决延迟任务

  定时执行:解决周期(周期)任务,比如每天数据统计

Celery的安装配置

  pip install celery

  消息中间件:RabbitMQ/Redis

  app=Celery(‘任务名’, broker=’xxx’, backend=’xxx’)

两种Celery任务结构

  提倡用包管理,结构更清晰

  1.

# 如果 Celery对象:Celery(...) 是放在一个模块下的
# 1)终端切换到该模块所在文件夹位置:scripts
# 2)执行启动worker的命令:celery worker -A 模块名 -l info -P eventlet
# 注:windows系统需要eventlet支持,Linux与MacOS直接执行:celery worker -A 模块名 -l info
# 注:模块名随意

  2.

# 如果 Celery对象:Celery(...) 是放在一个包下的
# 1)必须在这个包下建一个celery.py的文件,将Celery(...)产生对象的语句放在该文件中
# 2)执行启动worker的命令:celery worker -A 包名 -l info -P eventlet
# 注:windows系统需要eventlet支持,Linux与MacOS直接执行:celery worker -A 模块名 -l info
# 注:包名随意

包架构封装(多任务结构)

-celery_task  # 包 
    -__init__.py
    -celery.py  # 写app的py文件
    -home_task.py # 任务1 
    -order_task.py # 任务2
    -user_task.py # 任务3
--------------下面这些,跟上面可能在不同项目中----------------    
add_task.py   # 提交任务,django中提交
get_result.py # 查询结果,django中查询

Celery基本使用

  celery.py

from celery import Celery

# 消息中间件
broker = 'redis://127.0.0.1:6379/2'
# 结果存储
backend = 'redis://127.0.0.1:6379/1'
# 实例化得到对象
app = Celery('test', broker=broker, backend=backend, include=[
    'celery_task.home_task',
    'celery_task.order_task',
    'celery_task.user_task',
])
# 写好include,会去相应的py下检索任务,这些任务都被app管理

# 以后任务不写在这里了,放到单独的py文件中

  user_task.py

from .celery import app

@app.task
def send_sms(phone):
    print('手机号:%s,发送成功' % phone)
    return True

  add_task.py

from celery_task.user_task import send_sms

res=send_sms.apply_async(args=['1872637484872'])
print(res)

  get_result.py

# 通过代码把结果取出来
from celery_task.celery import app  # 借助于app
from celery.result import AsyncResult  # 导入一个类,来查询结果

id = 'd9692e2a-1e1f-436c-b58f-b25484cc5c56'
if __name__ == '__main__':
    res = AsyncResult(id=id, app=app)  # 根据id,去哪个app中找哪个任务,
    if res.successful(): # 执行成功
        result = res.get()
        print('任务执行成功')
        print(result) # 15
    elif res.failed():
        print('任务失败')
    elif res.status == 'PENDING':
        print('任务等待中被执行')
    elif res.status == 'RETRY':
        print('任务异常后正在重试')
    elif res.status == 'STARTED':
        print('任务已经开始被执行')

Celery执行异步任务

# 任务名.delay(参数,参数)
# 异步执行

Celery执行延迟任务

from datetime import datetime, timedelta
eta = datetime.utcnow() + timedelta(seconds=10)  # 5s后时间
# eta = datetime.utcnow() + timedelta(days=3)  # 3天后后时间
res = send_sms.apply_async(args=['17777777'], eta=eta)
print(res)

Celery执行定时任务

###### 第一步:在app中写入定时任务
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = False
### celery的配置信息---结束###

#### 定时任务
from datetime import timedelta
from celery.schedules import crontab
app.conf.beat_schedule = {
    'send_sms_5': {
        'task': 'celery_task.user_task.send_sms',  # 哪个任务
        'schedule': timedelta(seconds=5),  # 每5s干一次
        # 'schedule': crontab(hour=8, day_of_week=1),  # 每周一早八点
        'args': ('18988377473',),
    },
}


###### 第一步:启动worker
celery -A celery_task worker -l info
####  第三步:启动beat   【【【【注意路径】】】】】
celery -A celery_task beat -l info


### 本质是beat 5s钟提交一次任务,worker执行

Django中使用Celery

# 第一步:把包copy到项目路径下
luffy_api
  celery_task
      user_task.py
      order_task.py
      home_task.py
      celery.py
      __init__.py
      
# 第二步:在要提交任务的地方,导入执行
from celery_task.user_task import create_user
class TestView(APIView):
    def get(self, requeste):
        create_user.delay('12222222','lqznb','lqz12345')
        return Response('用户创建任务已经提交')
      
# 第三步:启动worker


# 有的情况下也可以把task放到不用的app中

  

posted @ 2022-08-30 21:36  那就凑个整吧  阅读(33)  评论(0编辑  收藏  举报