专栏首页程序员同行者Django项目中使用celery做异步任务

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 很详细

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • spring开发_JDBC操作MySQL数据库_使用xml配置事务管理

    http://www.cnblogs.com/hongten/archive/2012/03/09/java_spring_jdbc.html

    Hongten
  • Java Web 网络留言板

    guestbook:id ,name,phone,email,title,content,time;                   <pk>id

    Hongten
  • Tornado网站开发!前端、后端、人脸识别登录功能一节课全部实现!

    云飞
  • Python大牛带你一节课开发一个自定义翻译网站

    涉及知识点: web前端模板应用,模板语言应用 web后端开发,数据库入库,查询 爬虫开发,cookie保持,js加密 推荐下小编的Python学习群54211...

    云飞
  • Java Web JDBC数据源

    <?xml version='1.0' encoding='utf-8'?> <!--   Licensed to the Apache Software Fo...

    Hongten
  • java高并发锁的3种实现

    提到锁,大家可能都会想到synchronized关键字,使用它的确可以解决一切并发问题,但是对于系统吞吐要求更高的,在这里提供了几个小技巧,帮助大家减小锁粒度,...

    哲洛不闹
  • spring开发_JDBC操作MySQL数据库

    http://www.cnblogs.com/hongten/gallery/image/112450.html

    Hongten
  • spring开发_Spring+Struts2

    http://www.cnblogs.com/hongten/gallery/image/112920.html

    Hongten
  • Java Web ConnectionPool (连接池技术)

    Hongten
  • Java Web Commons-Utils (数据库连接方法)

        数据库驱动类:Oracle: ojdbc6.jar                   MySQL: mysql-connector-java-5.1....

    Hongten

扫码关注云+社区

领取腾讯云代金券