zoukankan      html  css  js  c++  java
  • Python—在Django中使用Celery

    一.Django中的请求

      Django Web中从一个http请求发起,到获得响应返回html页面的流程大致如下:

        http请求发起 

        经过中间件

          http handling(request解析) 

        url mapping(url匹配找到对应的View) 

        在View中进行逻辑(包括调用Model类进行数据库的增删改查)

        经过中间件

        返回对应的template/response。

      

      同步请求:所有逻辑处理、数据计算任务在View中处理完毕后返回response。在View处理任务时用户处于等待状态,直到页面返回结果。

      异步请求:View中先返回response,再在后台处理任务。用户无需等待,可以继续浏览网站。当任务处理完成时,我们可以再告知用户。

    二.Django中使用Celery

    安装

    pip3 install django-celery

    配置

      首先创建一个django项目,结构如下:

                    

        之后再settings.py的同级目录添加celeryconfig.py配置文件,更多配置信息可以参考官方文档。

    import djcelery
    from datetime import timedelta
    
    djcelery.setup_loader()
    
    # 导入任务
    CELERY_IMPORTS = [
        'celeryapp.tasks'
    ]
    # 设置队列
    CELERY_QUEUES = {
        'beat_tasks': {
            'exchange': 'beat_tasks',
            'exchange_type': 'direct',
            'binding_key': 'beat_tasks'
        },
        'work_queue': {
            'exchange': 'work_queue',
            'exchange_type': 'direct',
            'binding_key': 'work_queue'
        }
    }
    # 设置默认列队,不符合其他队列的任务放在默认队列
    CELERY_DEFAULT_QUEUE = 'work_queue'
    
    # 有些情况下可以防止死锁
    CELERYD_FORCE_EXECV = True
    
    # 设置并发数量
    CELERYD_CONCURRENCY = 4
    
    # 每个worker最多执行100个任务,防止泄露内存
    CELERYD_MAX_TASKS_PER_CHILD = 100
    
    # 单个任务最多执行时间
    CELERYD_TASK_TIME_LIMIT = 12 * 30
    
    # 设置定时执行
    CELERYBAET_SCHEDULE = {
        'task1': {
            'task': 'course-task',
            'schedule': timedelta(seconds=5),
            'options': {
                'queue': 'beat_tasks'
            }
        }
    }
    
    CELERY_ACCEPT_CONTENT = ['pickle', 'json', ]
    
    BROKER_BACKEND = 'redis'
    BROKER_URL = 'redis://localhost:6379/1'
    CELERY_RESULT_BACKEND = 'redis://localhost:6379/2'
    celeryconfig.py
    from .celeryconfig import *  # 导入Celery配置信息
    
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'celeryapp.apps.CeleryappConfig',
        'djcelery'  # 注册celery
    ]
    settings.py
    import time
    from celery.task import Task
    
    
    class Course(Task):
        name = 'course-task'
    
        def run(self, *args, **kwargs):
            print('start...')
            time.sleep(3)
            print(f'args={args},kwargs={kwargs}')
            print('end task....')
    tasks.py
    from django.http import JsonResponse
    from celeryapp.tasks import Course
    
    
    def course(request, *args, **kwargs):
        # 执行异步任务
        print("start course...")
        # Course.delay()
        # 可以使用apply_async传递参数,指定队列
        Course.apply_async(args=('hello',), queue='work_queue')
        print("end course...")
        return JsonResponse({'result': 'ok'})
    views.py
    from django.contrib import admin
    from django.urls import path
    from celeryapp.views import course
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('course/', course),
    ]
    urls.py

    启动redis作为消息中间人

    redis-server 

    启动django项目,然后访问http://localhost:8000/course/,触发任务

    python manage.py runserver

    启动worker

    python manage.py celery worker -l info   

        可以看到配置情况,以及任务的执行情况:

                

          

          

     启动beat

    python manage.py celery beat -l info

             

     三.常见错误

    ♦  AttributeError: ‘str’ object has no attribute ‘items’

    解决方法: redis版本过高,降低redis版本即可

    pip install redis==2.10.6

    ♦  from kombu.async.timer import Entry, Timer as Schedule, to_timestamp, logger SyntaxError: invalid syntax

      这个是python3.7目前不支持kombu,降低python版本至3.6即可,可以使用conda进行直接安装

    conda install python=3.6.8

     四.过程监控

      Celery提供了一个工具flower,将各个任务的执行情况、各个worker的健康状态进行监控并以可视化的方式展现。

    安装监控

    pip install flower

    执行flower

    python manage.py celery flower

    本地端口:5555查看监控

    刷新course页面,查看tasks,发现有刚刚执行完成的任务

      查看broker

     进入Monitor查看任务执行情况,执行成功,执行失败,消耗的时间,队列里面的任务情况

    点击的worker查看具体worker情况 

     可以给flower添加密码认证,添加之后再访问则需要输入用户名和密码

    python manage.py celery flower --basic_auth=username:password 
  • 相关阅读:
    使用scp进行远程数据传输时避免输入密码(scp without password)
    scons用户指南翻译(附gcc/g++参数详解)
    StringIO 模块用于在内存缓冲区中读写数据
    注意变换的顺序
    为什么static成员必须在类外初始化
    Visual Studio中删除所有空行
    rendering order of skybox
    解决VS中注释乱码的问题
    一道数论题目
    First Chance Exception
  • 原文地址:https://www.cnblogs.com/zivli/p/11517797.html
Copyright © 2011-2022 走看看