zoukankan      html  css  js  c++  java
  • 0041 django_celery任务处理(01 视图任务)

      程序中的任务主要有两类需求:

      一是视图触发任务:就是当更新一个数据时,需要对其它数据进行汇总,而且汇总的数据量大,这时候,需要分为两个进程来处理,一个进程是把数据更新后返回前端,二个进程是执行汇总任务。所谓视图触发任务,就是只有在需要的时候,根据条件去触发任务。

      二是定时触发任务:就是规定确定的时间去触发任务。比如:每周汇总一次,每月汇总一次。这类任务就叫定时触发任务。

      任务处理有很多插件,但Celery是处理超大规模的最优插件。我们选用Celery做为任务处理插件。

      本节主要介绍视图触发任务。

      新建一个名为CeleryDemo工程。安装好环境插件。

    1 在工程配置目录下(指包含settings.py的目录)创建celery.py文件

    from __future__ import absolute_import, unicode_literals
    import os
    from celery import Celery
    
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CeleryDemo.settings')  # 设置django环境,CeleryDemo为新建工程名
    app = Celery('CeleryDemo') # 为新建工程名
    app.config_from_object('django.conf:settings', namespace='CELERY')  # 使用CELERY_ 作为前缀,在settings中写配置
    app.autodiscover_tasks()  # 发现任务文件每个app下的task.py 

    2 修改工程配置目录下__init__.py文件

    from __future__ import absolute_import, unicode_literals
    from .celery import app as celery_app
    
    __all__ = ['celery_app'] 

    3 修改配置文件

    CELERY_BROKER_URL = 'redis://:cgl139@172.17.0.11:5379/26'  # Broker配置,使用Redis作为消息中间件
    CELERY_RESULT_BACKEND = 'redis://:cgl139@172.17.0.11:5379/26'  # BACKEND配置,这里使用redis
    CELERY_RESULT_SERIALIZER = 'json'  # 结果序列化方案 

    4 发布到服务器

      在PyCharm Terminal下发布,进程无法终止,因此在服务器上发布。

      在服务器重建一个虚拟环境,执行:

    # &表示可在后台运行,终止后,后台还会运行。
    python manage.py runserver 0.0.0.0:81 &
    # CeleryDemo表示新建的工程名
    celery worker -A CeleryDemo -l debug
    

      效果如下:

    5 编写任务

      在要执行任务的APP目录下,创建tasks.py文件,用于编写任务。

      注:tasks.py必须在APP目录下,而且文件名为能更改。

    from __future__ import absolute_import, unicode_literals
    from celery import shared_task
    
    
    @shared_task
    def add(x, y):
        print('========================执行add任务')
        return x + y
    
    
    @shared_task
    def mul(x, y):
        print('========================执行mul任务')
        return x * y

    5 编写视图

    from django.http import JsonResponse
    from nucleus import tasks
    from django.views import View
    
    
    # Create your views here.
    class Index(View):
        @classmethod
        def get(cls, request):
            res = tasks.add.delay(1, 3)
            # 任务逻辑
            return JsonResponse({'status': 'successful', 'task_id': res.task_id})
    

    6 编写url

    from django.contrib import admin
    from django.urls import path
    from nucleus.views import Index
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('Index/', Index.as_view(), ),
    ]
    

    7 服务器发布

      发布带任务的工程时,启动工程需要在后台运行,反复发布时需要终止之前的进程。常用有以下几个命令:

      &:在命令后空格+&,表示该命令可在后台执行

      lsof -i 81 :用于查看当前端口的任务

      kill -9 进程ID:用于删除当前进程

      确保之前进程已终止,重新发布,在工程目录(包含manage.py目录)下执行:

    python manage.py runserver 0.0.0.0:81 &
    # 启动工程后,ctrl+c 进入控制台,此时工程在后台运行
    celery worker -A CeleryDemo -l debug

    8 测试效果

      在浏览器访问Index接口,每访问一次,就可以看到任务执行一次,效果如下:

     9 检验进程

      现在,浏览器每请求一次,任务执行一次,那么,问题来了,是执行完任务,再返回,还是任务和返回同步进行呢?

      我们需要的,并不是先执行完任务再返回,不然,就不需要任务了。那我们改变一下代码任务代码,在任务执行的时候,等20秒,在浏览器请求的时候,是不是能先返回结果,20秒以后,再显示任务执行呢?修改tasks.py

    from __future__ import absolute_import, unicode_literals
    from celery import shared_task
    import time
    
    
    @shared_task
    def add(x, y):
        time.sleep(20)
        print('========================执行add任务')
        return x + y
    
    
    @shared_task
    def mul(x, y):
        print('========================执行mul任务')
        return x * y

      测试结果发现:和我们预料的一样,浏览器请求,马上就收到了返回结果。而任务要20秒以后,会自动执行!

  • 相关阅读:
    关于Tomcat的那些事儿(一)
    关于Spring的问题(一)
    关于Spring的@RequestBody的使用
    关于Eclipse切换所有分支
    关于使用BetterIntelliJ激活IntelliJ IDEA
    关于Elasticsearch的问题(一)
    关于Elasticsearch那些事
    关于LRU算法及Java实现
    自定义滚动条
    创建型模式之建造者模式
  • 原文地址:https://www.cnblogs.com/dorian/p/12418674.html
Copyright © 2011-2022 走看看