2018-12-28-celery在django中如何使用

个人博客地址——https://www.dogebug.cn/
GitHub地址——https://github.com/yanshigou/


title: “django-celery如何使用和配置”
date: 2018-12-28 13:55
author: dzt
subtitle: celery在django mysql数据库下的使用和配置
tags:

  • django
  • celery
  • mysql

上一篇文章我详细的写了如何在服务器上搭建异步任务队列项目
这篇就文章详细的写如何创建一个django-celery项目

前言

首先简单介绍一下,Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。我们通常使用它来实现异步任务(async task)和定时任务(crontab)。

它的架构组成如下图:

框架集成

  • Django django-celery
  • Pyramid pyramid_celery
  • Pylons celery-pylons
  • Flask 不需要
  • web2py web2py-celery
  • Tornado tornado-celery

正文

上面简单介绍了一下,从网上获取的图片和官方的文档

可以看到,Celery 主要包含以下几个模块:

任务模块 Task

包含异步任务和定时任务。其中,异步任务通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat 进程周期性地将任务发往任务队列。

消息中间件 Broker

Broker,即为任务调度队列,接收任务生产者发来的消息(即任务),将任务存入队列。Celery 本身不提供队列服务,官方推荐使用 RabbitMQ 和 Redis 等。

由于本项目比较小,使用django作为Broker

任务执行单元 Worker

Worker 是执行任务的处理单元,它实时监控消息队列,获取队列中调度的任务,并执行它。

任务结果存储 Backend

Backend 用于存储任务的执行结果,以供查询。同消息中间件一样,存储也可使用 RabbitMQ, Redis 和 MongoDB 等。

异步任务

使用 Celery 实现异步任务主要包含三个步骤:

创建一个 Celery 实例
启动 Celery Worker
应用程序调用异步任务

创建django项目和安装对应的环境我就不再说了

一、修改setting配置

#celery setting
import djcelery
djcelery.setup_loader() # 加载celery
BROKER_URL = 'django://ip:port'  # broker地址
BROKER_POOL_LIMIT = 0 # 连接池中可以打开最大连接数 如果设置成None或者0,连接池将会被禁用,并且每次使用连接都会重新建立连接并关闭。
CELERY_RESULT_BACKEND='djcelery.backends.database:DatabaseBackend' # 结果存储
CELERY_TIMEZONE='Asia/Shanghai' # 时区
CELERY_ENABLE_UTC = False # 关闭UTC
CELERYD_CONCURRENCY = 2      # celery worker并发数
CELERYD_MAX_TASKS_PER_CHILD = 4 # 每个worker最大执行任务数


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'djcelery', # djcelery
    'paopao', # appname
    'kombu.transport.django' # kombu.transport.django则是基于Django的broker
    
]
# 如果希望在部署环境中使用, 最重要的便是使用更稳定和可扩展的broker, 而不是
# kombu.transport.django.

celery任务并发只与celery配置项CELERYD_CONCURRENCY 有关,与CELERYD_MAX_TASKS_PER_CHILD没有关系,即CELERYD_CONCURRENCY=2,只能并发2个worker,此时运行较大的文件,执行两次可以看到两个task任务并行执行,而执行第三个任务时,开始排队,直到两个worker执行完毕。

celery执行完任务不释放内存与原worker一直没有被销毁有关,因此CELERYD_MAX_TASKS_PER_CHILD可以适当配置小点,而任务并发数与CELERYD_CONCURRENCY配置项有关,每增加一个worker必然增加内存消耗,同时也影响到一个worker何时被销毁,因为celery是均匀调度任务至每个worker,因此也不宜配置过大,适当配置。

二、在App下创建celery文件

# -*- coding: utf-8 -*-
from __future__ import absolute_import

import os

from celery import Celery


# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test_celery.settings')

from django.conf import settings  # noqa

app = Celery('paopao')

# Using a string here means the worker will not have to
# pickle the object when using Windows.
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下的init.py

from __future__ import absolute_import, unicode_literals


# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from paopao.celery import app as celery_app

四、创建task.py (tools/下)

# -*- coding: utf-8 -*-
from __future__ import absolute_import
from celery import shared_task


@shared_task(track_started=True)
def test_task(time1):
    pass # 自己的逻辑

五、创建App下的Views.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
from django.views.generic.base import View
from django.http import HttpResponse, HttpResponseRedirect
from tools.tasks import test_task, get_imei

class UploadView(LoginRequiredMixin, View):
    def post(self, request):
        form = ImeiInfoForm(request.POST, request.FILES)
        if form.is_valid():
            # 获取表单数据
            info = form.cleaned_data['info']
            filename = form.cleaned_data['filename']
            time1 = datetime.now()

            f = PLL()
            f.filename = filename
            f.info = info
            f.starttime = time1
            f.save()


            # 要注意 filename 为<class'django.core.files.uploadedfile.InMemoryUploadedFile'>
            # 名字不能直接等于str(filename), 不然无法保存上传文件
            result = test_task.delay(time1)  ## 这里就是把任务交给task去处理 
            p = PLL.objects.get(starttime=time1)
            p.task_id = result.id
            p.save()
            return HttpResponseRedirect('/uploaded/')

在test_task.delay(time1)处,就直接把任务交给task去处理,不用阻塞,直接返回到/uploaded/

六、同步数据库

python manage.py makemigrations
python manage.py migrate

七、运行

python manage.py runserver 0.0.0.0:8000 
python manage.py celery worker -A test_celey -l info # test_celey 项目名称

八、结果图

源码在我的github上 —> https://github.com/yanshigou/MyScripts/tree/master/test_celery

[2018-12-28 15:20:18,105: INFO/MainProcess] Connected to django://localhost//
[2018-12-28 15:20:18,137: WARNING/MainProcess] d:\virtualenv\py27\lib\site-packages\celery\fixups\django.py:265: UserWarning: Using settings.DEBUG leads to a memory leak, never use this setting in produc
tion environments!
  warnings.warn('Using settings.DEBUG leads to a memory leak, never '
[2018-12-28 15:20:18,137: WARNING/MainProcess] celery@DESKTOP-JP2T8KQ ready.

这就算celery运行成功

项目效果图

个人博客地址——https://www.dogebug.cn/
GitHub地址——https://github.com/yanshigou/

禁止不留原创地址、署名的转载
本人保留所有法定权利。违者必究

展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值