django-celery实现异步任务,并在后台运行(守护进程)

对于开发人员,尤其要注重用户体验,毕竟没有用户使用,那么开发将毫无意义。
Celery异步处理框架,可用于执行耗时任务,比如发送邮件、文件上传,图像处理等等比较耗时的操作,这样用户不需要等待很久,可大大提高用户体验。

一、Celery介绍

  1. 简介
    Celery 是一个简单、灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具。

    它是一个专注于实时处理的任务队列,同时也支持任务调度。

    Celery 有广泛、多样的用户与贡献者社区。

    Celery 是开源的,使用 BSD 许可证 授权。

  2. 优点
    简单:配置项目少,在项目中直接导入使用

    灵活:celery的很多组件都支持灵活拓展

    高可用:当任务执行失败后,它会自动重新执行

    快速:单进程的celery每秒执行上百万个任务

二、Celery配置

因为电脑上有原来安装的redis数据库,所以我们使用redis的作为celery任务队列;
传送门:Windows和Linux(Centos7)下的Redis安装及使用

项目和app创建不过多说明,直接进入主题

  1. 安装依赖包

    pip install celery
    pip install django-celery
    pip install redis
    
  2. settings.py配置

    # celery中间人 redis://redis ip地址:端口/数据库号
    BROKER_URL = 'redis://localhost:6379/1'
    # celery结果返回,可用于跟踪结果
    CELERY_RESULT_BACKEND = 'redis://localhost:6379/1'
     
    # celery内容等消息的格式设置
    CELERY_ACCEPT_CONTENT = ['application/json', ]
    CELERY_TASK_SERIALIZER = 'json'
    CELERY_RESULT_SERIALIZER = 'json'
     
    # celery时区设置,使用settings中TIME_ZONE同样的时区
    CELERY_TIMEZONE = TIME_ZONE
    
  3. settings.py的同级目录下创建celery.py

    from __future__ import absolute_import, unicode_literals
     
    from celery import Celery
    from django.conf import settings
    import os
     
    # 获取当前文件夹名,即为该Django的项目名
    project_name = os.path.split(os.path.abspath('.'))[-1]
    project_settings = '%s.settings' % project_name
     
    # 设置环境变量
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', project_settings)
     
    # 实例化Celery
    app = Celery(project_name)
     
    # 使用django的settings文件配置celery
    app.config_from_object('django.conf:settings')
     
    # Celery加载所有注册的应用
    app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
    

    第一行导入不能换位置,只能在首行,否则会报错

  4. 为方便导入,把实例化celery的app放到__init__.py里(settings.py同级目录下的__init__.py

    from __future__ import absolute_import, unicode_literals
    
    # 引入celery实例对象
    from .celery import app as celery_app
    
  5. 根目录(manage.py同级目录)下创建celery_tasks目录,然后在celery_tasks目录下创建tasks.py(此文件名必须是tasks),并把耗时任务写进去

    from celery_test import celery_app #celery_test为我的项目名
    from app1 import models #app1为我的app名
    import time
    from celery import platforms
    platforms.C_FORCE_ROOT = True
    
    @celery_app.task
    def login_ip(ip):
        models.Login_ip.objects.create(ip=ip)
        time.sleep(10)
        print('登录ip存储成功')
    
  6. 在view中调用

    from django.shortcuts import render
    from celery_tasks.tasks import login_ip
    # Create your views here.
    
    def index(request):
        ip = '127.0.0.1'
        login_ip.delay(ip) #异步调用
        return render(request, 'index.html')
    

    注:使用.delay()进行异步调用

  7. 以上配置完成后项目目录结构如下

    ├──celery_test
    	├── celery_test
    	│	├── __init__.py
    	│	├── asgi.py
    	│	├── celery.py
    	│	├── settings.py
    	│	├── urls.py
    	│	└── wsgi.py
    	├── app1
    	│	├── migrations
    	│	├── __init__.py
    	│	├── admin.py
    	│	├── apps.py
    	│	├── models.py
    	│	└── views.py
    	├── celery_tasks
    	│	└── tasks.py
    	├── templates
    	│   └── index.html
    	└── manage.py
    

三、启动celery

必须先启动redis服务,安装和简单使用请参考:Windows和Linux(Centos7)下的Redis安装及使用
方法一:在managy同级文件目录下,输入命令(celery_test为我的项目名):

celery -A celery_test worker -l info

下列形式说明启动正常

(venv) F:\celery_test>celery -A celery_test worker -l info
......
DEBUG leads to a memory leak, never use this setting in production environments!
  warnings.warn('Using settings.DEBUG leads to a memory leak, never '
[2019-12-21 19:14:28,550: WARNING/MainProcess] celery@DESKTOP-ORHB3U3 ready.

方法二:守护进程方式启动,日志记录在celerylog.log里(celery_test为我的项目名):

celery multi start w1 -A celery_test -l info --logfile = celerylog.log --pidfile = celerypid.pid

停止:celery multi stop w1 -A celery_test -l info
重启:celery multi restart w1 -A celery_test -l info

启动过程中可能会出现的报错

四、启动Django项目

正常启动即可:python manage.py runserver

如大家发现问题,欢迎留言交流

发布了63 篇原创文章 · 获赞 87 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_44110998/article/details/103631952