celery和定时任务

https://www.jianshu.com/p/6f8576a37a3e

同步和异步请求概述

在讲celery之前,先说一下同步请求和异步请求
    同步请求:所有逻辑处理、数据计算任务在view中处理完毕返回response,在views处理任务时,用户处于等待状态,直到页面返回结果。
    异步请求:view中现将结果返回response,再在后台处理任务。用户无需等待,可以继续浏览网站。当任务处理完成时,我们可以再告知用户

为什么会需要消息队列(MQ)?

    原因:由于高并发环境下,由于来不及同步处理请求,请求往往会发生阻塞,比如大量的insert,update之类的请求同时到达数据库,直接导致无数的行锁表锁,甚至最后请求堆积过多,从而触发too many connections错误。使用消息队列,可以一步处理请求,从而减轻系统的压力

队列概述

消息队列:是分布式系统中重要的组件
当不需要立即获取结果,但是并发量又需要进行控制的时候,差不多就需要使用消息队列的时候
消息队列主要解决了应用耦合,异步处理,流量削峰等问题:
当前使用的消息队列有:RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等,而部分数据库如Redis、Mysql以及phxsql也可实现消息队列的功能。


celery

概述:当视图函数执行某些耗时操作的时候,用户界面则为一直请求(加载)用户体验不好,使用celery进行异步加载

步骤

1.任务:task
2.队列:queue
3.工人:worker
4.broker:负责调度

(1)celery解决的问题

1.耗时的任务执行
2.定时任务

(2)安装

pip install celery
pip install celery-with-redis
pip install django-celery

(3)配置settings

在INSTALLED_APPS添加如下代码
INSTALLED_APPS = [
    ...
    'App',
    'djcelery',
]
import djcelery
djcelery.setup_loader() #初始化
BROKER_URL = 'redis://127.0.0.1:6379/0' #进行调度的地址 加载执行的数据库0
CELERY_IMPORTS = ('App.task') #导入装有任务的py文件

(4)创建task.py

from  celery import task
@task
def test1():
      print('走到当前的任务了')
      time.sleep(5)
      print(''任务执行完毕'')
(5)生成celery所需的表
python manage.py migrate

(6)在工程目录下创建celery.py(与settings.py同级)

from __future__ import absolute_import

import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'whthas_home.settings')

app = Celery('portal')

app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

(7)在工程init.py文件中添加代码如下(与settings.py同级)

from .celery import app as celery_app

(8)在视图中导入任务

from django.shortcuts import render,HttpResponse
from App.task import test1

def index(req):
    if req.method == 'GET':
        test1.delay() #将耗时任务放到 队列里 异步加载
        return render(req,'index.html')

(9)启动redis

1.redis-server
2.redis-cli

(10)启动worker

python manage.py celery worker  --loglevel=info  # 详细展示当前的执行信息

二、定时执行一个或多个任务

(1).定时执行一个任务

settings.py添加代码如下:

from datetime import timedelta
CELERYBEAT_SCHEDULE = {
    'schedule-test':{
        'task':'App.task.test1', #定时执行的任务的函数名称
        'schedule':timedelta(seconds=7) #定时执行的间隔时间
    }
}

起动顺序

1.启动django

python manage.py runserver

2.启动broker

python manage.py celery broker --loglevel=info

3.启动定时任务

python manange.py celery beat --loglevel=info
(2)定时执行多个任务
from datetime import timedelta
CELERYBEAT_SCHEDULE = {
    'schedule-test':{
        'task':'App.task.test1', #定时执行的任务的函数名称
        'schedule':timedelta(seconds=7) #定时执行的间隔时间
    },
    'schedule-test2':{
        'task':'App.task.test2', #定时执行的任务的函数名称
        'schedule':timedelta(seconds=7), #定时执行的间隔时间
        'args':(3,) #定时任务传参
    }
}

task.py

from celery import task

import time

@task
def test1():
    print('走到当前的任务了')
    time.sleep(5)
    print('任务执行完毕')


@task
def test2(i):
    print('打印',i)
    time.sleep(5)
    print('打印',i)
image

你可能感兴趣的:(celery和定时任务)