Celery

作者: 梦醒家先生 | 来源:发表于2018-07-18 21:20 被阅读0次

许多Django应用需要执行异步任务, 以便不耽误http request的执行. 我们也可以选择许多方法来完成异步任务, 使用Celery是一个比较好的选择, 因为Celery有着大量的社区支持, 能够完美的扩展, 和Django结合的也很好. Celery不仅能在Django中使用, 还能在其他地方被大量的使用. 因此一旦学会使用Celery, 我们可以很方便的在其他项目中使用它.

问题分析:
  • 在网络请求出现问题时,是一个耗时操作。在同一个主线程中,耗时请求就要等待主线程执行完毕之后,在去加载请求操作。
解决问题:
  • 使用线程,异步执行 耗时操作(原生的threading线程会出现GIL全局解释器锁的问题)
弊端解决:
  • 使用celery,解决GIL全局解释器锁的问题

Celery介绍

Celery的主要用处是执行异步任务, 可以选择延期或定时执行功能. 为什么需要执行异步任务呢?

  • 假设用户正发起一个request, 并等待request完成后返回. 在这一request后面的view功能中, 我们可能需要执行一段花费很长时间的程序任务, 这一时间可能远远大于用户能忍受的范围. 当这一任务并不需要立刻执行时, 我们便可以使用Celery在后台执行, 而不影响用户浏览网页. 当有任务需要访问远程服务器完成时, 我们往往都无法确定需要花费的时间.

  • 定期执行某些任务. 比如每小时需要检查一下天气预报, 然后将数据储存到数据库中. 我们可以编写这一任务, 然后让Celery每小时执行一次. 这样我们的web应用便能获取最新的天气预报信息.

  • 我们这里所讲的任务task, 就是一个Python功能(function). 定期执行一个任务可以被认为是延时执行该功能. 我们可以使用Celery延迟5分钟调用function task1, 并传入参数(1, 2, 3). 或者我们也可以每天午夜运行该function.

1. 我们偏向于将Celery放入项目中, 便于task访问统一数据库和Django设置.

2. 当task准备运行时, Celery会将其放入列队queue中. queue中储存着可以运行的task的list. 我们可以使用多个queue, 但为了简单, 这里我们只使用一个.

3. 将任务task放入queue就像加入todo list一样. 为了使task运行, 我们还需要在其他线程中运行的苦工worker. worker实时观察着代运行的task, 并逐一运行这些task. 你可以使用多个worker, 通常他们位于不同服务器上. 同样为了简单起见, 我们这只是用一个worker.
Celery执行流程图:

image.png
执行流程
  1. 在项目文件下创建celery_tasks应用用于保存celery异步任务
  2. 创建一个celery的启动文件,相当与Django manage文件--> 相对与流程图worker
  3. 创建一个config文件,用于连接redis,任务队列中--> 相对与流程图broker
  4. 创建一个sms目录,celery_tasks/sms/目录下创建tasks.py文件,用于保存发送短信的异步任务-->任务的发布文件
  5. 在视图中使用delay方法调用任务,执行异步线程方法--> 相对与流程图任务发布方法中心

安装Celery
使用pip在vietualenv中安装:

pip install django-celery

创建Celery应用:

  • 目录结构


    image.png

一. 在celery_tasks目录下创建config.py文件,用于保存celery的配置信息

# 配置连接的redis, 任务broker
broker_url = "redis://127.0.0.1/14"

二. 在celery_tasks目录下创建main.py文件,用于作为celery的启动文件

from celery import Celery

# 为celery使用django配置文件进行设置
import os
if not os.getenv('DJANGO_SETTINGS_MODULE'):
    #'project.settings.dev':项目的配置文件,添加Celery配置
    os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings.dev'

# 创建celery应用
app = Celery('jianshu')

# 导入celery配置
app.config_from_object('celery_tasks.config')

# 自动注册celery任务(自动查询sms文件下的方法)
app.autodiscover_tasks(['celery_tasks.sms'])

三.在celery_tasks目录下创建sms目录,用于放置的异步任务相关代码

# 存放异步任务的发布队列方法
import logging
import time

from celery_tasks.main import app

# 调用配置文件中日志器
logger = logging.getLogger("django")

#app装饰器能够在视图中调用该异步任务
@app.task(name='send_sms_code')
def send_sms_code():
    # 发送短信验证码
    try:
       '''此处异步任务方法'''
       ....
        time.sleep(10)
    except Exception as e:
        logger.error("发送验证码短信[异常])

三. 在项目views.py中改写主线程中的任务,使用celery异步任务

from celery_tasks.sms.tasks import send_sms_code

.....
send_sms_code.delay()

四.启动Celery应用

# 终端启动命令(在vietualenv中cd到celery_tasks目录下,)
celery -A celery_tasks.main worker -l info

相关文章

网友评论

      本文标题:Celery

      本文链接:https://www.haomeiwen.com/subject/ypjapftx.html