通用技术 django-celery 学习笔记

尹全旺 · 2018年04月12日 · 最后由 尹全旺 回复于 2018年04月13日 · 2196 次阅读

Django-Celery 是什么东东?

最近在做 HttpRunnerManager 发现一个缺陷:1、如果多用例 (特别是有需要延时的接口) 批量执行,那么 views 视图必须执行完毕才能返回 (同步执行),这样大大的占用了 I/O 资源,得不到释放,所以用例执行必须采用异步执行方式。2、django-celery 可以灵活运用其作定时任务配置和调度。基于此目的,自己学习了下 django-celery 模块,下面总结下主要步骤,以供大家参考 (windows7 环境)。

环境篇

1、Rabbitmq:celery 在执行任务时需要一个消息中间件来接收和发送任务消息,以及存储任务结果,一般使用 RabbitMQ 或 Redis,官方推荐的 RabbitMQ
windows 环境安装时注意需要先安装 ERL!设置好环境变量即可,安装完毕启动 rabbitmq,成功后访问:http://localhost:15672guest、guest,成功部署后如下:,默认用户名、密码

配置篇

1、安装 django-celery、flower 库,初始化 django-celery 相关数据表,就是执行 python manange.py migrate
2、可在对应的 django 工程/HttpRunnerManager//HttpRunnerManager/新建 celery.py 模块:

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery

# set the default Django settings module for the 'celery' program.
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'HttpRunnerManager.settings')

app = Celery('HttpRunnerManager')#自己更改这个,比如我的是HttpRunnerManager

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

3、对应 app 目录新建 tasks.py 注意只有 tasks 才会去加载任务!!

# Create your tasks here
from __future__ import absolute_import, unicode_literals

import time
from celery import shared_task


@shared_task
def delay(x, y):
    time.sleep(10)
    print('the sum is:',x+y)
    return x + y


@shared_task
def mul(x, y):
    return x * y


@shared_task
def xsum(numbers):
    return sum(numbers)

目录如下:

4、新增 settings.py 相关配置,以下是我的配置:

djcelery.setup_loader()

BROKER_URL = 'amqp://guest:guest@127.0.0.1:5672//' #rabbitmq
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'#定时任务调度 配置存储到数据库 所以可以web端动态添加哦
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend' #ji结果存储,我配置的是存储到数据库
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

CELERY_TASK_RESULT_EXPIRES = 3600  # celery任务执行结果的超时时间,
CELERYD_CONCURRENCY = 50  # celery worker的并发数 也是命令行-c指定的数目,事实上实践发现并不是worker也多越好,保证任务不堆积,加上一定新增任务的预留就可以

启动篇

1、执行:python manage.py celery -HttpRunnerManager worker --loglevel=INFO # 启动 worker,自动加载 tasks
2、执行:python manage.py celery beat --loglevel=INFO # 监听后面定时任务
3、执行:celery flower #http://localhost:5555/tasks web 后台界面可以查看任务执行状态
1、比如上面步骤 3 有个 delay 函数延时 10 秒,我们放到 view 里面执行,方位/api/test_celey,可以立即返回 ok,马上释放 IO 资源,交给消息队列异步执行中间过程:

def test_celery(request):
    add.delay(1, 2)
    return HttpResponse('ok')

2、如果不自己开发 web 界面,可以利用 django 自带 admin 增加定时任务 (本质就是插数据库),,加载后可以看到后台数据 (djcelery_periodictask):


3、效果图:
tasks 监控页面:

后台 tasks 日志:

结束语

顺便打个广告,之前由于自己的事情耽搁了,HttpRunnerManager 即将上线 api 管理,报告管理还有定时任务这个功能,希望各路大神能多多指点

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 8 条回复 时间 点赞
仅楼主可见
尹全旺 · #2 · 2018年04月13日 Author
仅楼主可见
尹全旺 · #3 · 2018年04月13日 Author
仅楼主可见

可以只用一条命令同时启动 Worker 和 beat ,在启动 Worker 的命令里加一个 -B 试一下

志阳、 回复

嗯,多谢,但是这样只能启动一个 worker 的吧?

仅楼主可见
仅楼主可见
yca 回复

已经加了

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册