Django项目中使用celery做异步任务
异步任务介绍
在写项目过程中经常会遇到一些耗时的任务, 比如:发送邮件、发送短信等等~。这些操作如果都同步执行耗时长对用户体验不友好,在这种情况下就可以把任务放在后台异步执行
celery就是用于处理异步任务的框架,celery能完成的功能远不止异步任务,还有一个很常用的功能定时任务
架构图

Celery包含如下组件:
Celery Beat:任务调度器,Beat进程会读取配置文件的内容,周期性地将配置中到期需要执行的任务发送给任务队列。Celery Worker:执行任务的消费者,通常会在多台服务器运行多个消费者来提高执行效率。Broker:消息代理,或者叫作消息中间件,接受任务生产者发送过来的任务消息,存进队列再按序分发给任务消费方(通常是消息队列或者数据库)。Producer:调用了Celery提供的API、函数或者装饰器而产生任务并交给任务队列处理的都是任务生产者。Result Backend:任务处理完后保存状态信息和结果,以供查询。Celery默认已支持Redis、RabbitMQ、MongoDB、Django ORM、SQLAlchemy等方式。
Celery 安装
pip install django-celery celery-with-redis
项目结构
[vagrant@reboot test_drf]$ tree opsweb/
opsweb/
├── apps
│ ├── account
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── __init__.py
│ │ ├── migrations
│ │ ├── models.py
│ │ ├── __pycache__
│ │ ├── tasks.py
│ │ ├── tests.py
│ │ └── views.py
├── celerybeat.pid
├── logs
│ ├── celery
│ │ ├── beat.log
│ │ └── celery.log
├── manage.py
├── opsweb
│ ├── celery.py
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
加载celery app(settings文件中)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'rest_framework',
'rest_framework_swagger',
'account',
'djcelery' # celery app 很强大
]
添加Celery全局配置(settings文件中)
# Celery
import djcelery
djcelery.setup_loader() # 加载djcelery
CELERY_TIMEZONE = TIME_ZONE
CELERY_ENABLE_UTC = True
# 允许的格式
CELERY_ACCEPT_CONTENT = ['pickle', 'json', 'yaml']
BROKER_URL = 'redis://127.0.0.1:6379/0' # redis作为中间件
BROKER_TRANSPORT = 'redis'
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler' # Backend数据库
# CELERYD_LOG_FILE = BASE_DIR + "/logs/celery/celery.log" # log路径
# CELERYBEAT_LOG_FILE = BASE_DIR + "/logs/celery/beat.log" # beat log路径
同步Celery表到数据库
python manage.py migrate
创建celery.py文件(与settings同级)
import os
import django
from celery import Celery
from django.conf import settings
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'opsweb.settings')
django.setup()
app = Celery('opsweb')
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))
创建任务文件
在需要使用异步任务的app中创建tasks.py,写入对应的任务函数,博主喜欢把tasks放在对应的app下,其实放在其他目录下也可以的,看个人习惯
from opsweb.celery import app
from celery.schedules import crontab
import traceback
from django.contrib.auth.models import User
import os
@app.task(name="create_user")
def useradd(username):
try:
print(username)
except:
print('fail')
traceback.print_exc()
触发任务
在对应的视图中导入tasks中的任务函数调用即可
from account.tasks import useradd
# 调用异步任务函数
useradd.delay('username')
启动Celery
进入opsweb工程下,启动Celery
[vagrant@reboot opsweb]$celery -A opsweb worker -B -l info
或:
[vagrant@reboot opsweb]$python manage.py celery worker -B -l info
备注:
本场景用户访问触发任务,流程如下:
用户页面上点击事件->调用任务/定时计划任务->任务进入redis队列
->如果celery启动则依次执行任务->如果celery没启动,则会存到redis
队列里,一旦启动就依次执行
启动Django
[vagrant@reboot opsweb]$python manage.py runserver 0:8000
测试
页面上触发了异步任务就会在celery日志里看到任务信息,我这里只是写了简单的任务例子
[2018-09-01 23:56:59,704: WARNING/Worker-2] hello
[2018-09-01 23:56:59,707: INFO/MainProcess] Received task: create_user[c9724e23-b9ba-44fc-b195-6b1153d2c161]
[2018-09-01 23:56:59,708: INFO/MainProcess] Task create_user[f3b3e644-b8aa-4679-8a42-0efc2574abf6] succeeded in 0.0038937819999773637s: None
计划任务 - djcelery
djcelery app提供了定时任务的功能,注册并同步到数据库之后,会生产五个表,结构如下:
MariaDB [test002]> show tables
-> ;
+---------------------------+
| Tables_in_test002 |
+---------------------------+
...
| djcelery_crontabschedule |
| djcelery_intervalschedule |
| djcelery_periodictask |
| djcelery_periodictasks |
| djcelery_taskstate |
| djcelery_workerstate |
+---------------------------+
在django后台可以看到注册的表

每个任务可以接受参数

定时任务函数
from opsweb.celery import app
@app.task(name="create_user" )
def create_user(*args,**kwargs): # 分别接收后台传入的列表和字典参数
print (args,kwargs)
启动Celery beat
[vagrant@reboot opsweb]$ python manage.py celery beat # 启动定时任务
Celery会通过celery beat进程来完成. Celerybeat会保持运行, 一旦到了某一定期任务需要执行时, Celery beat便将其加入到queue中
supervisor管理Celery任务
配置如下
- 主动触发任务
celery_worker.conf
[program:celery_worker]
# 进入工作目录
directory=/vagrant/test_drf/opsweb
# 执行celery指令
command=python manage.py celery worker -B -l info
autorestart=true
loglevel=info
redirect_stderr=true
stdout_logfile=/var/log/supervisor/celery_worker.log
- 定时任务触发
celery_beat.conf 同上, 区别如下:
[program:celery_beat]
command=python manage.py celery beat
stdout_logfile=/var/log/supervisor/celery_beat.log
一些不错的文章
http://www.cnblogs.com/znicy/p/5626040.html Django中使用celery,非常经典
https://www.cnblogs.com/huangxiaoxue/p/7266253.html 基于celery开发的平台,非常棒
http://python.jobbole.com/81953/ 刘天斯大神 经典案例
http://www.imooc.com/article/16164 慕课网老师博客
http://blog.csdn.net/michael_lbs/article/details/74923367 python+django+djcelery
http://blog.csdn.net/lizhihua0925/article/details/53842110 model api
http://www.jianshu.com/p/7085dcc70d0e 挺好
http://blog.csdn.net/crb912/article/details/78344659 很详细
Django项目中使用celery做异步任务的更多相关文章
- 异步任务利器Celery(二)在django项目中使用Celery
Celery 4.0支持django1.8及以上的版本,低于1.8的项目使用Celery 3.1. 一个django项目的组织如下: - proj/ - manage.py - proj/ - __i ...
- celery 分布式异步任务框架(celery简单使用、celery多任务结构、celery定时任务、celery计划任务、celery在Django项目中使用Python脚本调用Django环境)
一.celery简介: Celery 是一个强大的 分布式任务队列 的 异步处理框架,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行.我们通常使用它来实现异步任务(async tas ...
- [翻译]在Django项目中添加谷歌统计(Google Analytics)
原文:<Google Analytics tracking code into Django projects, the easy way> 对我来说,制作一个可扩展的Django应用随时 ...
- django 项目中使用多数据库 multiple databases
假如在一个django项目中使用到了不只一个数据库, 其实这在大一点的工程中很常见,比如主从库 那么会涉及到如下一些东西 1, 定义 在settings中的DATABASE中定义会使用到的数据,比如除 ...
- 【技术博客】JWT的认证机制Django项目中应用
开发组在开发过程中,都不可避免地遇到了一些困难或问题,但都最终想出办法克服了.我们认为这样的经验是有必要记录下来的,因此就有了[技术博客]. JWT的认证机制Django项目中应用 这篇技术博客基于软 ...
- Django项目中使用Redis
Django项目中使用Redis DjangoRedis 1 redis Redis 是一个 key-value 存储系统,常用于缓存的存储.django-redis 基于 BSD 许可, 是一个使 ...
- 擦他丫的,今天在Django项目中引用静态文件jQuery.js 就是引入报错,终于找到原因了!
擦 ,今天在Django项目中引用静态文件jQuery.js 就是引入报错,终于找到原因了! 问题在于我使用的谷歌浏览器,默认使用了缓存,导致每次访问同一个url时,都返回的是缓存里面的东西.通过谷歌 ...
- django 项目中的 favicon.ico 处理
django 项目中的 favicon.ico 处理 (django == 2.0.6) 1. 引入模块: from django.views.generic.base import Redirec ...
- Django项目中模板标签及模板的继承与引用【网站中快速布置广告】
Django项目中模板标签及模板的继承与引用 常见模板标签 {% static %} {% for x in range(x) %}{% endfor %} 循环的序号{% forloop %} 循环 ...
随机推荐
- CORSFilter 跨域资源访问
CORS 定义 Cross-Origin Resource Sharing(CORS)跨来源资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,是 ...
- MYSQL分组合并函数
MySQL中group_concat函数完整的语法如下:group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符' ...
- nlp算法工程师养成记 目标要求
时间规定: 2018.12.07-2018.02.15 能力养成: linux, shell python, c++(会多少算多少) tensorflow, keras, pytorch(tf优先) ...
- Linux mysql 联表查询
在rhce考试题中,第21.22题为数据库查询题 题目: 在system1上创建一个Maria DB数据库,名为Contacts,要求: 数据库应该包含来自数据库users.mdb的内容,数据库只能被 ...
- [leetcode]4. Median of Two Sorted Arrays俩有序数组的中位数
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...
- Maven Nexus3 安装,私服搭建
为啥搭建Maven私服? 如果没有私服,我们所需的所有构件都需要通过maven的中央仓库和第三方的Maven仓库下载到本地,而一个团队中的所有人都重复的从maven仓库下载构件无疑加大了仓库的负载和浪 ...
- PHP 实现单链表
数据结构是计算机存储.组织数据的方式,结构不同那么数据的检索方式和效率都不一样, 常用的数据结构有 数组 .栈 .队列 .链表 .树.堆 今天讲下单链表,单链表是一种链式存取的数据结构, 跟顺序链表 ...
- 【转】C#单元测试,带你快速入门
[转]C#单元测试,带你快速入门 注:本文示例环境 VS2017 XUnit 2.2.0 单元测试框架 xunit.runner.visualstudio 2.2.0 测试运行工具 Moq 4.7.1 ...
- 2019.02.21 bzo1038: [ZJOI2008]瞭望塔(半平面交)
传送门 题意:给出一个nnn个点的轮廓,要求找一个高度最小的点使得它能够看见所有拐点. 思路:之间建半平面交然后取半平面交上的每个交点和每个轮廓更新答案即可. 代码: #include<bits ...
- 叙述 activemq 与spring 主题实现 小功能实现
在上一篇文章里 我说到了 maven的配置 我现在直接说 xml配置 首先我先描述 生产者的信息 <?xml version="1.0" encoding="UT ...