Django异步任务

一、项目存在的问题:

假如,当前请求发送短信的服务区负载较大,或者网络状况不好,服务器进入等待状态,停止提供其他服务,由于上述问题,开发者迫切需要在发出短信指令后,服务器还可以继续提供其他服务的能力

异步任务:当任务被发起,不会阻塞主线程,会到另外的线程或者进程当中运行,知道结束,返回结果

1、需要解决的思路

首先服务器接收到发送短信的请求

然后服务器将这个任务存放到任务队列中

然后其他服务器领取任务,开始执行

2、开发者可以自己编写上述的需求:

(1)首先定义存放任务和存放返回数据的队列

        queue队列,代码级的生产者和消费者,通常用于线程间的数据通信

        redis,noSQL数据库,但是可以使用内存进行数据存储,存储高效,适合当做一些快速,高效需求的容器

        rabbitmiq专业的开源的小写队列

(2)然后当有任务触发,将任务下发到队列中

(3)其他服务器或者进程轮询检查任务队列,一旦发现任务,立刻执行

二、Django的Celery

1、python的三方也编写了类似的产品:Celery

执行原理

user 用户

borker 任务容器

workers执行任务的角色

store 保存结果的容器

2、python的Celery框架,是一个专门用来处理异步任务的框架。

celery最常用的两种任务容器和结果容器:

(1)Redis,onSQL数据库,Redis被频繁的使用在并发,分布式当中,Redis可以将数据存在内存当中,运算快。

(2)RabbitMQ消息队列,是一个成熟的用于任务存储和转发的消息队列

3、安装Celery

Django将Celery进行了封装(di-celery),只需要下载注册,配置就可以使用

(1)安装redis

解压即安装

(2)安装django-celery

pip install django-celery==3.2.2

(3)安装python-redis

pip install redis==2.10.6 # 可能出现兼容问题

4、启动redis

在解压Redis文件中

redis-server.exe redis.windows.conf

启动成功

访问redis,关闭redis

redis-cli.exe

shutdown

4、Celery异步任务

1、安装djcelery到INSTALL_APPS当中

安装到APPS当中

2、创建存放任务的APP

activate Django37

python manage.py startapp  CeleryTask

3、在setting中编写Celery代码

#celery

import djcelery

djcelery.setup_loader() #重新加载celery

BROKER_URL = "redis://127.0.0.1:6379/1" #任务存放的容器

CELERY_IMPORTS =("CeleryTask.task") #任务清单

CELERY_TIMEZONE = "Asia/Shanghai" #时区,用于定时任务

CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler" #核心调度器

3、主目录中创建celery文件

添加配置信息

import os

from celery import Celery

from django.conf import settings

#设置celery的环境变量和django-celery的工作目录

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CeleryTask.settings")

#实例化celery应用

app = Celery("our_project")

#加载celery配置

app.config_from_object("django.conf:settings")

#如果项目当中有task.py,那么celery使用app当中的task来生成任务

app.autodiscover_tasks(lambda :settings.INSTALLED_APPS)

4、APP中task文件,编写功能函数

from __future__ import absolute_import #绝对导入

from Qshop.celery import  app

from ronglian_sms_sdk import SmsSDK

from Qshop.settings import accId,accToken,appId,tid

@app.task

def say_hi():

    print("hi man")

@app.task

def say_hello(number):

    print("你好,这是第{}次执行".format(number))

@app.task

def send_message(code,mobile = '13331153360',timer="5"):

    sdk = SmsSDK(accId, accToken, appId)

    datas = (code, timer)

    resp = sdk.sendMessage(tid, mobile, datas)

    print(resp)

5、启动Celery

第一次启动需要进行数据迁移

python manage.py check

python manage.py makemigrations

python manage.py migrate

    启动celery

    python manage.py celery worker --loglevel=INFO

6、修改源码

(1)python3.7将async这个单词定义为关键词,所以不能作为模块名称,需要我们对源码修改

修改沙箱文件名称

(2)跟据步骤跳转修改变量名称,使用全局修改

asynchronous

7、启动功能函数内的函数,发布任务,可开启多个服务器

    python manage.py celery worker --loglevel=INFO

8、使用多服务器可实现发送短信,发送邮件,不影响其他服务器工作

Celery定时任务

例如:电商业务,比如每月的15日,通知会员进行秒杀活动,

通常我们使用LInux的crontab计划任务,可以完成大部分的事情,但是使用调用crontab不是很方便,Celery也推出了自己的定时任务管理

添加定时任务配置

在setting中添加配置

#celery定时任务

from celery.schedules import timedelta,crontab

CELERYBEAT_SCHEDULE = {

    u"测试01": {

        "task": "CeleryTask.task.say_hi", #任务

        "schedule": timedelta(seconds = 2) #计时,没2秒执行一次

    }

}

启动worker

python manage.py chelery worker --loglevel=INFO

启动定时任务

python manage.py celery beat --loglevel=INFO

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容