zoukankan      html  css  js  c++  java
  • Django+Celery学习笔记3——django+celery+redis实现异步任务与定时任务

      引言

      前面已经学习了celery+redis的异步和定时任务,下面介绍如何结合django来使用。

      环境配置

      在动手之前,一定要准备好的是环境,celery版本有很多,在使用过程中如何版本与django和redis版本不配套,将会很麻烦。

      我这里的环境如下:

    celery==4.3.0
    Django==2.2.2
    django-celery-beat==1.5.0
    django-celery-results==1.1.2
    kombu==4.6.11   -- celery的依赖
    PyMySQL==0.9.3
    redis==3.2.1
    python-crontab==2.5.1
    

      创建项目

      再复习一下创建django项目的命令,打开cmd窗口,输入:

    django-admin startproject 项目名
    

      进入刚刚创建的项目根目录下,创建应用(app),输入:

    python manage.py startapp 应用名
    

      

       

      在应用celerytest根目录下新建tasks.py文件,用于定义计划任务,注意此处只能以tasks命名(设计如此)

      在django的项目目录(djangocelerydemo)中创建celery.py(与settings.py在同一级目录)文件,当然你也可以命名成celeryconfig.py文件,

      这个文件没有要求,为啥要创建这个文件呢? 

      因为,要将Celery与Django项目一起使用,必须首先定义Celery库的实例,也就是创建celery的应用。文件放在此处,这种设置方法可以让celery自动在所有app中查找tasks文件,比较适合多人多APP同时开发的中大型项目 详情参考:Using Celery with Django

      项目结构与配置

      

       第一步,在djangocelerydemo/setting.py文件配置如下:

    # APP配置
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'django_celery_beat',
        'django_celery_results',  # 查看 celery 执行结果
        'celerytest.apps.CelerytestConfig',
    ]
    
    # 数据库配置
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'djangocelerydemo',
            'HOST': '127.0.0.1',
            'PORT': '3306',
            'USER': 'root',
            'PASSWORD': '123456',
        }
    }
    
    # 时区与celery相关配置
    LANGUAGE_CODE = 'zh-hans'
    # 简体中文界面
    
    TIME_ZONE = 'Asia/Shanghai'
    # 亚洲/上海时区
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = False
    # 不使用国际标准时间
    
    
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/2.2/howto/static-files/
    
    STATIC_URL = '/static/'
    # django-celery-beat
    
    # django-celery-results
    
    CELERY_ENABLE_UTC = False
    # 不使用国际标准时间
    CELERY_TIMEZONE = 'Asia/Shanghai'
    # 使用亚洲/上海时区
    DJANGO_CELERY_BEAT_TZ_AWARE = False
    # 解决时区问题
    CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
    # 使用0号数据库
    
    CELERY_BROKER_TRANSPORT = 'redis'
    # 使用redis作为中间件
    CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
    # 自定义调度类,使用Django的ORM
    CELERY_RESULT_BACKEND = 'django-db'
    # 任务结果,使用Django的ORM
    CELERY_ACCEPT_CONTENT = ['application/json']
    # 设置任务接收的序列化类型
    CELERY_TASK_SERIALIZER = 'json'
    # 设置任务序列化方式
    CELERY_RESULT_SERIALIZER = 'json'
    # 设置结果序列化方式
    

      注意,如何你的函数返回的不是json, 将报错:

    kombu.exceptions.EncodeError: Object of type 'set' is not JSON serializable
    

      解决:

    CELERY_TASK_SERIALIZER = 'pickle'
    # 设置任务序列化方式
    CELERY_RESULT_SERIALIZER = 'pickle'
    # 设置结果序列化方式
    CELERY_ACCEPT_CONTENT = ['pickle', 'json']
    # 设置任务接收的序列化类型
    

      将之前setting中三个替换成这三个即可。原因:celery4版本的 默认使用 JSON 作为 serializer ,而 celery3版本的默认使用 pickle。所以为了让报错消除,需要添加以上设置。

      第二步,在djangocelerydemo/celeryconfig.py文件配置如下:

    from __future__ import absolute_import, unicode_literals
    import os
    
    from celery import Celery, platforms
    from django.utils.datetime_safe import datetime
    
    # 获取当前文件夹名,即为该 Django 的项目名
    project_name = os.path.split(os.path.abspath('.'))[-1]
    project_settings = '%s.settings' % project_name
    print(project_settings)
    
    # 设置默认celery命令行的环境变量
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangocelerydemo.settings')
    
    
    # 实例化 Celery,项目名称
    app = Celery('djangocelerydemo')
    
    # 解决时区问题
    app.now = datetime.now
    
    # 使用 django 的 settings 文件配置 celery
    app.config_from_object('django.conf:settings', namespace='CELERY')
    
    # 从所有应用中加载任务模块tasks.py
    app.autodiscover_tasks()
    
    # 解决celery不能root用户启动的问题
    platforms.C_FORCE_ROOT = True
    

      

      第三步,在djangocelerydemo/__init__.py文件配置如下:

    # 引入celery实例对象
    from __future__ import absolute_import, unicode_literals
    from djangocelerydemo.celeryconfig import app as celery_app
    
    __all__ = ('celery_app',)
    
    
    import pymysql
    pymysql.install_as_MySQLdb()
    

      这里不是app下面的__init__.py文件,是项目下面的。

      第四步,在celerytest/tasks.py文件配置如下:

    # Create your tasks here
    from __future__ import absolute_import, unicode_literals
    
    from djangocelerydemo.celeryconfig import app
    
    @app.task
    def plan_task_1():
        print("任务_1已运行!")
        return {"任务_1:success"}
    
    
    @app.task
    def plan_task_2():
        print("任务_2已运行!")
        return  {"任务_2:success"}
    

      第五步,最后别忘记配置apps.py了,如:

    from django.apps import AppConfig
    
    
    class CelerytestConfig(AppConfig):
        name = 'celerytest'
    

      第六步,数据迁移,因为没有模型,不需要激活,所以在项目根目录下直接输入:

    python manage.py migrate
    

      

       如果看到这7大金刚,证明你前面所有的工作已经正确的完成了。

      温馨提示一下,上面的文件中,凡是用到celery文件的,需在第一行(习惯)加入代码:

    from __future__ import absolute_import, unicode_literals
    

      

      定时任务配置

      上面基本上配置完后,创建管理员账号,如:

    python manage createsuperuser
    

      访问系统地址:http://127.0.0.1:1234/admin/

       名词解析:

      界面中 CELERY RESULTS 为 django_celery_results 创建的用于保存任务结果的数据库表。
      Periodic tasks 下面则是由 django_celery_beat 创建的用于保存 Celery 任务及其执行规则的几张数据库表,具体含义如下:
      1、Clocked:定义在具体某个时间点触发的执行规则
      2、Crontabs:类似于 Linux 系统下 crontab 的语法,定时任务的执行时间
      3、Intervals:定义任务重复执行的时间间隔
      4、Periodic tasks:具体某个待执行的任务,需要与其他表(Clocked、Crontabs、Intervals、Solar events)中定义的执行规则相关联
      5、Solar events:根据日升和日落等太阳运行轨迹确定执行规则

       

      配置一个每十秒执行一次的规则,步骤如下:

      配置定时计划任务,如图:

      执行定时任务

      前面已经讲过了异步任务和定时任务的命令,现在再次复习一下:

      在项目根目录下执行异步任务命令:

    celery -A pro_name worker -l info
    

      这里还是要注意,win10会报一个这样的错误:

    ValueError: not enough values to unpack (expected 3, got 0)
    

      需要在上面命令加一个:

    celery -A pro_name worker -l info -P eventlet

      pro_name是django项目的名称

       成功后,你会看见两个任务。

       在项目根目录下执行定时任务命令:

    celery -A pro_name beat -l info
    

      

      每十秒执行一次:

       执行的结果:

      在web界面上可以查到:

      这里需要注意:celery.backend_cleanup。有一个内建的周期性任务将删除过期的任务结果(celery.backend_cleanup),前提是 celery beat 已经被启用。这个任务每天上午4点运行。值 None 或者 0 意思是结果永不删除(取决于后端声明)

      注意事项

      这里如果安装celery或者运行任务调度器出现如下报错:

    ModuleNotFoundError: No module named 'vine.five'
    

      

       celery安装的时候,会把amqp、vine和kombu一起安装完成,所以一定要注意celery版本要和amqp、vine和kombu匹配,不然你将很麻烦。

      正常版本是:

    # 这四个要匹配
    amqp==2.6.1
    celery==4.3.0
    kombu==4.6.11
    vine==1.3.0
    
    
    # 另外匹配项
    redis==3.2.1
    Django==2.2.2
    django-celery-beat==1.5.0
    django-celery-results==1.1.2
    PyMySQL==0.9.3
    

      这样的话,你不会看到上面的报错信息。

      总结

      以上就是django+celery+redis实例,celery很强大,需要深入研究。如果对python测试开发相关技术感兴趣的伙伴,欢迎加入测试开发学习交流QQ群:696400122,不积跬步,无以至千里。

  • 相关阅读:
    SQL Server数据库文件存储目录转移
    窗口管理器 dwm安装
    arch linux 安装
    如何在windows 2003(虚拟主机)上面部署MVC3
    .NET接入微信支付(一)JS API接入 V3
    MongoDB部署实战(一)MongoDB在windows平台分片集群部署
    .NET接入UnionPay银联支付(一)手机wap支付
    cas4.2.7 集群服务搭建
    JAVA计算整数的位数
    JAVA求解质因数
  • 原文地址:https://www.cnblogs.com/liudinglong/p/13876124.html
Copyright © 2011-2022 走看看