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秒以后,會自動執行!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM