1、异步开发
开发中有一些任务就是耗时的,这时就需要异步任务来解决这个问题。
1.1 celery框架
负责Python进行异步通信的框架,可以实现分布式任务执行,定时任务执行,使用Celery执行任务,任务不会阻塞主进程,会单独执行,完成后返回结果
user:发起任务的人
broker:存放任务的队列,一般情况可以使用rabbitmq或者redis作为broker
workers: 执行任务对象,可以是一个线程,一个进程或者一个服务器
store: 存放结果的容器
1、在发送任务之前,worker启动
2、用户发起任务,任务通常以函数的形式存在
3、执行完的结果放回store当中
Celery 最常用的两种任务容器和结果容器是:
1、Redis ,NoSQL数据库,Redis被频繁的使用在并发,分布式当中,Redis可以将数据存在内存当中,运算快。
2、RabbitMQ 消息队列,是一个成熟的用于任务存储和转发的消息队列。
python拥有celery框架,但是这个框架结合django是有一些冗余代码的。所以django开发出了封装好的celery框架,djcelery。
1.2 异步服务器部署
1.2.1 redis的安装与启动
解压安装包,在命令行切换到解压后的目录下,执行下面命令启动redis服务
redis-server.exe redis.windows.conf
注意:
关闭redis服务,直接关闭窗口可能不会关闭服务,还可能会造成数据的丢失,需要在命令行中关闭
# 连接redis服务器
redis-cli.exe
# 关闭服务器
shutdown
1.2.2 安装python包
pip install Django-celery==3.2.2
pip install Django-redis
pip install redis==2.10.6
1.2.3 配置celery服务器
1、在项目中settings配置当中安装djcelery
2、创建celery.py和tasks.py文件,名字任意,存放celery配置和任务信息。
3、编写配置信息
from celery import Celery, platforms
from django.conf import settings
import os
# 设置celery的默认工作目录
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shop.settings")
# 启动celery项目
app = Celery()
# 项目加载配置
app.config_from_object("django.conf:settings")
# 加载djcelery
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
# 支持以root启动
platforms.C_FORCE_ROOT = True
1.2.4 编写任务
在tasks.py文件中编写需要异步处理的任务。
from .celery import app
import time
@app.task
def task1():
"""无参方法"""
print("task1...begin...")
time.sleep(10) # 模拟耗时操作
print("task1...end...")
@app.task
def task2(a, b):
"""有参方法"""
print("task2...begin...a={},b={}".format(a, b))
time.sleep(10) # 模拟耗时操作
print("task2...end...")
return a + b
1.2.5 启动worker
因为celery中实体类需要生成表,需要同步数据库。
python manage.py check
python manage.py makemigrations
python manage.py migtate
启动命令
python manage.py celery worker --loglevel=INFO
报错:python3将async这个单词定义为关键词,所以不可以作为模块名称,需要对源码修改。
方法一:
修改kombu中的async文件名为asynchronous
然后修改报错的文档中所有的async为asynchronous
方法二:
修改源码后得出,主要是celery和kombu文件夹内的源码出错,直接把改好的文件覆盖site-packages文件夹里面的celery和kombu文件夹即可解决。
文件地址:https://gitee.com/yzc_1/python/tree/master/tutorial/images/22
修改完成后即可启动
1.2.6 发布任务
from .tasks import task1,task2
task1.delay() # 发布任务
task2.delay(1,2) # 发布带参数的任务
1.3 celery定时任务
通常我们使用Linux的crontab计划任务,可以完成大部分的事情。但是Celery也推出了自己的定时任务管理。
1.3.1 settings增加配置
from celery.schedules import timedelta, crontab
CELERYBEAT_SCHEDULE = {
u'测试任务一': {
"task": "shop.tasks.task1", # 定时任务要执行的任务
"schedule": timedelta(seconds=3), # 每秒执行一次
"args": (), # 任务函数的参数
},
u'测试任务二': {
"task": "shop.tasks.task2", # 定时任务要执行的任务
"schedule": crontab(minute='0', hour='8', day_of_month='15'), # 时间设置,每月十五号的八点执行任务
"args": (1, 2), # 任务函数的参数
},
}
1.3.2 启动worker
python manage.py celery worker --loglevel=INFO
1.3.3 启动定时任务
python manage.py celery beat --loglevel=INFO