Django项目中使用celery分布式任务方法

项目框架目录树:

django_celery
|
├── course  # 新建应用
│   ├── admin.py
│   ├── __init__.py
│   ├── migrations
│   ├── models.py
│   ├── tasks.py  # 任务模块
│   ├── urls.py  # 路由文件
│   └── views.py
├── db.sqlite3
├── django_celery
│   ├── celeryconfig.py  # celery配置文件
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

安装依赖包:

pip3 install django-celery
pip3 install redis

第一步:在项目settings.py同级目录下创建celeryconfig.py文件保存celery配置信息,内容如下:

import djcelery
from datetime import timedelta


# 加载django中注册的应用中的任务(例如我们此项目中course应用中的tasks.py任务)
djcelery.setup_loader()


# 手动定义queue队列
CELERY_QUEUES = {
    # 定时任务队列
    'beat_tasks-1': {
        'exchange': 'beat_tasks-1', 
        'exchange_type': 'direct',
        'binding_key': 'beat_tasks-1'
     },
    'beat_tasks-2': {
        'exchange': 'beat_tasks-2',
        'exchange_type': 'direct',
        'binding_key': 'beat_tasks-2',
    },
}


# 设置默认队列,不指定任务队列时默认使用普通任务队列
CELERY_DEFAULT_QUEUE = 'work_queue'


# 导入应用中任务文件
CELERY_IMPORTS = (
    'course.tasks',
)


# 有些情况下可以防止死锁
CELERYD_FORCE_EXECV = True

# 设置并发的worker数量
CELERYD_CONCURRENCY = 4

# 设置失败允许重试
CELERYD_ACKS_LATE = True

# 每个worker最多执行100个任务被销毁,可以防止内存泄漏
CELERYD_MAX_TASKS_PER_CHILD = 100

# 单个任务的最大运行时间,超时会被杀死
CELERYD_TASK_TIME_LIMIT = 12 * 30


# 定时任务
CELERYBEAT_SCHEDULE = {
    'task1': {
        'task': 'course-task',  # 任务名
        'schedule': timedelta(seconds=10),  # 设置每10秒执行一次任务
        # 'args': (10, 100)  # 任务函数传参
        'options': {
			'queue': 'beat_tasks-1'  # 指定任务队列
		}
    },
    'task2': {
        'task': 'course-task',  # 任务名
        'schedule': timedelta(seconds=10),  # 设置每10秒执行一次任务
        # 'args': (100, 1000)  # 任务函数传参
        'options': {
			'queue': 'beat_tasks-2'  # 指定任务队列
		}
    }
}

第二步:在项目settings.py配置文件中添加以下内容

# 注册应用中添加我们的course应用和要使用的异步队列应用djcelery
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'djcelery',  # 注册djcelery
    'course',  # 注册我们的
)
# 导入celery配置信息
from .celeryconfig import *

# 以下配置可以放在celeryconfig.py文件中,但为了方便配置,放在settings文件中更好
BROKER_BACKEND = 'redis'
BROKER_URL = 'redis://localhost:6379/1'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/2'

第三步:在项目跟路由配置文件urls.py文件中配置我们course应用路由:

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    # 当访问地址为http://127.0.0.1:8000时对应到我们course应用路由
    url(r'', include('course.urls', namespace='course')),
]

第四步:在course应用的urls.py文件中,定义视图处理函数路由

from django.conf.urls import url
from .views import do  # 导入视图处理函数

urlpatterns = [
	# 当访问地址为http://127.0.0.1:8000/do时,对应到course应用中views.py文件中的视图处理函数do
    url(r'^do/', do, name='do'),  # 为视图函数添加访问路由
]

第五步:在应用中创建tasks.py任务文件,测试内容如下:

import time
from celery.task import Task


class CourseTask(Task):
    # 给任务起名字
    name = 'course-task'

    def run(self, *args, **kwargs):
        print("start course task")
        # 模拟耗时
        time.sleep(4)
        print("args={}, kwargs={}".format(args, kwargs))
        print("end course task")

第六步:在course应用views.py视图文件中定义视图函数,在视图函数中调用任务

from django.http import JsonResponse
from django.shortcuts import render
from .tasks import CourseTask


def do(request):
    # 执行异步任务
    print('start do request')
    # 调用任务
    CourseTask.delay()
    # apply_async() 方法可以直接传参并且指定任务队列,使用更方便
    # CourseTask.apply_async(args=('hello',), queue=('work_queue'))
    print('end do request')
    return JsonResponse({'result': 'OK'})

说明:在任务函数中,我们模拟了4秒的延迟,正常情况下,我们访问该视图处理函数时执行到任务调用将会等待4秒,直到任务模块完成,才会继续向下执行,但我们使用了celery异步任务队列,此处将不会阻塞,直接返回response信息。

第七步:启动任务队列

# 由于定时任务发送给了两个不同的队列,因此worker队列必须同时监听这两个队列,来进行消费

python3 manage.py celery worker -l info -n workerA.%h -Q beat_tasks-1

python3 manage.py celery worker -l info -n workerA.%h -Q beat_tasks-2
  • 注意点:

如果使用supervisor进行管理时,启动命令应该如下(注意是两个%号):
python3 manage.py celery worker -l info -n workerA.%%h -Q beat_tasks-1

第八步:触发定时任务

python3 manage.py celery beat -l info

第九步:启动django项目

python3 manage.py runserver

第九步:打开浏览器访问地址http://127.0.0.1:8000/do
在这里插入图片描述

说明:我们在任务函数中设置的4秒延迟并没有阻塞我们任务函数后面的代码执行,当我们回车后直接返回了json数据。



使用flower管理监控celery任务

(1)安装依赖包flower

pip3 install flower

(2)启动

django manage.py celery flower

(3)在浏览器中查看

http://127.0.0.1:5555

(4)为了安全起见,通常启动时设置账号密码

django manage.py celery flower --basic_auth=用户名:密码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值