Django+Celery实现定时任务的示例


Posted in Python onJune 23, 2021
目录
  • 一、前言
  • 二、配置使用
  • 定义与触发任务
  • 扩展
  • 三、Django中使用定时任务
  • 二次开发

 

一、前言

  Celery是一个基于python开发的分布式任务队列,而做python WEB开发最为流行的框架莫属Django,但是Django的请求处理过程都是同步的无法实现异步任务,若要实现异步任务处理需要通过其他方式(前端的一般解决方案是ajax操作),而后台Celery就是不错的选择。倘若一个用户在执行某些操作需要等待很久才返回,这大大降低了网站的吞吐量。

​另一方面,当我们需要处理一些定时任务时Celery强大的生态环境也是他的优势。

​在刚刚学习如何使用Celery时可能会觉得难以入手,我利用工作之余研究这些文档前前后后也花了快一个周的样子,目前已经可以满足我的需求,所以静下心多写多测试,加油。

Django+Celery实现定时任务的示例

 

二、配置使用

  celery很容易集成到Django框架中,当然如果想要实现定时任务的话还需要安装django-celery-beta插件,后面会说明。需要注意的是Celery4.0只支持Django版本>=1.8的,如果是小于1.8版本需要使用Celery3.1。

本示例使用主要依赖包如下:

celery==4.2.1
Django==1.11.7
django-celery-beat==1.4.0
django-celery-results==1.0.4
PyMySQL==0.9.2
redis==2.10.6

配置

  新建立项目celery_demo,目录结构(每个app下多了个tasks文件,用于定义任务):

celery_demo
├── app01
│   ├── __init__.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tasks.py
│   └── views.py
├── manage.py
├── celery_demo
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── templates

在项目目录celery_demo/celery_demo/目录下新建celery.py:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author:wd
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery

# 设置django环境
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'celery_demo.settings')  
app = Celery('celery_demo')
#  使用CELERY_ 作为前缀,在settings中写配置
app.config_from_object('django.conf:settings', namespace='CELERY') 
# 发现任务文件每个app下的task.py
app.autodiscover_tasks()

celery_demo/celery_demo/__init__.py写入:

from __future__ import absolute_import, unicode_literals
from .celery import app as celery_app
__all__ = ['celery_app']

celery_demo/celery_demo/settings.py写入:

CELERY_BROKER_URL = 'redis://10.1.210.69:6379/0' # Broker配置,使用Redis作为消息中间件

CELERY_RESULT_BACKEND = 'redis://10.1.210.69:6379/0' # BACKEND配置,这里使用redis

CELERY_RESULT_SERIALIZER = 'json' # 结果序列化方案

进入项目的celery_demo目录启动worker

celery worker -A taskproj -l debug

 

定义与触发任务

任务定义在每个tasks文件中,app01/tasks.py

from __future__ import absolute_import, unicode_literals
from celery import shared_task
@shared_task
def add(x, y):
    return x + y
@shared_task
def mul(x, y):
    return x * y

视图中触发任务

from django.http import JsonResponse
from app01 import tasks

# Create your views here.

def index(request,*args,**kwargs):
    res=tasks.add.delay(1,3)
    #任务逻辑
    return JsonResponse({'status':'successful','task_id':res.task_id})

访问http://127.0.0.1:8000/index

Django+Celery实现定时任务的示例

若想获取任务结果,可以通过task_id使用AsyncResult获取结果,还可以直接通过backend获取:

Django+Celery实现定时任务的示例

 

扩展

  除了redis、rabbitmq能做结果存储外,还可以使用Django的orm作为结果存储,当然需要安装依赖插件,这样的好处在于我们可以直接通过django的数据查看到任务状态,同时为可以制定更多的操作,下面介绍如何使用orm作为结果存储。

安装

pip install django-celery-results

配置settings.py,注册app

INSTALLED_APPS = (
    ...,
    'django_celery_results',
)

修改backend配置,将Redis改为django-db

#CELERY_RESULT_BACKEND = 'redis://10.1.210.69:6379/0' # BACKEND配置,这里使用redis

CELERY_RESULT_BACKEND = 'django-db'  #使用django orm 作为结果存储

修改数据库

python3 manage.py migrate django_celery_results

此时会看到数据库会多创建:

Django+Celery实现定时任务的示例 

当然你有时候需要对task表进行操作,以下源码的表结构定义:

class TaskResult(models.Model):
    """Task result/status."""

    task_id = models.CharField(_('task id'), max_length=255, unique=True)
    task_name = models.CharField(_('task name'), null=True, max_length=255)
    task_args = models.TextField(_('task arguments'), null=True)
    task_kwargs = models.TextField(_('task kwargs'), null=True)
    status = models.CharField(_('state'), max_length=50,
                              default=states.PENDING,
                              choices=TASK_STATE_CHOICES
                              )
    content_type = models.CharField(_('content type'), max_length=128)
    content_encoding = models.CharField(_('content encoding'), max_length=64)
    result = models.TextField(null=True, default=None, editable=False)
    date_done = models.DateTimeField(_('done at'), auto_now=True)
    traceback = models.TextField(_('traceback'), blank=True, null=True)
    hidden = models.BooleanField(editable=False, default=False, db_index=True)
    meta = models.TextField(null=True, default=None, editable=False)

    objects = managers.TaskResultManager()

    class Meta:
        """Table information."""

        ordering = ['-date_done']

        verbose_name = _('task result')
        verbose_name_plural = _('task results')

    def as_dict(self):
        return {
            'task_id': self.task_id,
            'task_name': self.task_name,
            'task_args': self.task_args,
            'task_kwargs': self.task_kwargs,
            'status': self.status,
            'result': self.result,
            'date_done': self.date_done,
            'traceback': self.traceback,
            'meta': self.meta,
        }

    def __str__(self):
        return '<Task: {0.task_id} ({0.status})>'.format(self)

 

三、Django中使用定时任务

  如果想要在django中使用定时任务功能同样是靠beat完成任务发送功能,当在Django中使用定时任务时,需要安装django-celery-beat插件。以下将介绍使用过程。

安装配置

1.beat插件安装

pip3 install django-celery-beat

2.注册APP

INSTALLED_APPS = [
    ....   
    'django_celery_beat',
]

3.数据库变更

python3 manage.py migrate django_celery_beat

4.分别启动woker和beta

celery -A proj beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler  #启动beta 调度器使用数据库

celery worker -A taskproj -l info #启动woker

5.配置admin

urls.py写入:

# urls.py
from django.conf.urls import url
from django.contrib import admin
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

6.创建用户

python3 manage.py createsuperuser

7.登录admin进行管理(地址http://127.0.0.1:8000/admin)并且还可以看到我们上次使用orm作为结果存储的表。

http://127.0.0.1:8000/admin/login/?next=/admin/

Django+Celery实现定时任务的示例

使用示例:

Django+Celery实现定时任务的示例

Django+Celery实现定时任务的示例

查看结果:

Django+Celery实现定时任务的示例

 

二次开发

  django-celery-beat插件本质上是对数据库表变化检查,一旦有数据库表改变,调度器重新读取任务进行调度,所以如果想自己定制的任务页面,只需要操作beat插件的四张表就可以了。当然你还可以自己定义调度器,django-celery-beat插件已经内置了model,只需要进行导入便可进行orm操作,以下我用django reset api进行示例:

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'django_celery_results',
    'django_celery_beat',
    'rest_framework',
]

urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index$', views.index),
    url(r'^res$', views.get_res),
    url(r'^tasks$', views.TaskView.as_view({'get':'list'})),
]

views.py

from django_celery_beat.models import PeriodicTask  #倒入插件model
from rest_framework import serializers
from rest_framework import pagination
from rest_framework.viewsets import ModelViewSet
class Userserializer(serializers.ModelSerializer):
    class Meta:
        model = PeriodicTask
        fields = '__all__'

class Mypagination(pagination.PageNumberPagination):
    """自定义分页"""
    page_size=2
    page_query_param = 'p'
    page_size_query_param='size'
    max_page_size=4

class TaskView(ModelViewSet):
    queryset = PeriodicTask.objects.all()
    serializer_class = Userserializer
    permission_classes = []
    pagination_class = Mypagination

访问http://127.0.0.1:8000/tasks如下:

Django+Celery实现定时任务的示例

参考资料:

W-D:https://www.cnblogs.com/wdliu/p/9530219.html

还在琢磨:https://blog.csdn.net/mbl114/article/details/78047175

Celery文档:http://docs.celeryproject.org/en/latest/

以上就是Django+Celery实现定时任务的示例的详细内容,更多关于Django Celery定时任务的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python正则表达式re模块详解
Jun 25 Python
python高手之路python处理excel文件(方法汇总)
Jan 07 Python
python妙用之编码的转换详解
Apr 21 Python
Python判断文件和字符串编码类型的实例
Dec 21 Python
用tensorflow构建线性回归模型的示例代码
Mar 05 Python
Django基于ORM操作数据库的方法详解
Mar 27 Python
python用plt画图时,cmp设置方法
Dec 13 Python
对Python w和w+权限的区别详解
Jan 23 Python
通过python改变图片特定区域的颜色详解
Jul 15 Python
Python使用__new__()方法为对象分配内存及返回对象的引用示例
Sep 20 Python
Python jiaba库的使用详解
Nov 23 Python
使用Python开发贪吃蛇游戏 SnakeGame
Apr 30 Python
Python django中如何使用restful框架
Python基础之变量的相关知识总结
Jun 23 #Python
浅谈Python数学建模之固定费用问题
浅谈Python数学建模之整数规划
浅谈Python数学建模之数据导入
Jun 23 #Python
python四种出行路线规划的实现
浅谈Python数学建模之线性规划
Jun 23 #Python
You might like
PHP中feof()函数实例测试
2014/08/23 PHP
php实现修改新闻时删除图片的方法
2015/05/12 PHP
php无限分类使用concat如何实现
2015/11/05 PHP
PHP微信开发之查询城市天气
2016/06/23 PHP
PHP实现的操作数组类库定义与用法示例
2019/05/24 PHP
编写针对IE的JS代码两种编写方法
2013/01/30 Javascript
js简单的表格添加行和删除行操作示例
2014/03/31 Javascript
JQuery实现可直接编辑的表格
2015/04/16 Javascript
基于javascript实现浏览器滚动条快到底部时自动加载数据
2015/11/30 Javascript
JavaScript记录光标在编辑器中位置的实现方法
2016/04/22 Javascript
JavaScript中setter和getter方法介绍
2016/07/11 Javascript
js实现PC端根据IP定位当前城市地理位置
2017/02/22 Javascript
JQuery实现文字无缝滚动效果示例代码(Marquee插件)
2017/03/07 Javascript
jquery学习笔记之无new构建详解
2017/12/07 jQuery
深入理解 webpack 文件打包机制(小结)
2018/01/08 Javascript
vue中如何实现后台管理系统的权限控制的方法示例
2018/09/19 Javascript
[01:06:54]DOTA2-DPC中国联赛 正赛 SAG vs DLG BO3 第二场 2月28日
2021/03/11 DOTA
python和shell变量互相传递的几种方法
2013/11/20 Python
用Python展示动态规则法用以解决重叠子问题的示例
2015/04/02 Python
基于python yield机制的异步操作同步化编程模型
2016/03/18 Python
python获取list下标及其值的简单方法
2016/09/12 Python
Python实现的从右到左字符串替换方法示例
2018/07/06 Python
python通过tcp发送xml报文的方法
2018/12/28 Python
Python Image模块基本图像处理操作小结
2019/04/13 Python
python对指定字符串逆序的6种方法(小结)
2020/04/02 Python
Python中使用filter过滤列表的一个小技巧分享
2020/05/02 Python
django美化后台django-suit的安装配置操作
2020/07/12 Python
Pandas中两个dataframe的交集和差集的示例代码
2020/12/13 Python
美国维生素、补充剂、保健食品购物网站:Vitacost
2016/08/05 全球购物
Agoda台湾官网:国内外订房2折起
2018/03/20 全球购物
日本航空官方网站:JAL
2019/06/19 全球购物
节能宣传周活动总结
2014/05/08 职场文书
西双版纳导游词
2015/02/03 职场文书
行政司机岗位职责
2015/04/10 职场文书
JavaScript使用canvas绘制坐标和线
2021/04/28 Javascript
Python+Selenium实现抖音、快手、B站、小红书、微视、百度好看视频、西瓜视频、微信视频号、搜狐视频、一点号、大风号、趣头条等短视频自动发布
2022/04/13 Python