非同步任務-----django-celery
非同步任務 ---- django-celery
大家的知道celery的使用,網上也有很多的教程。因為最近在使用django來完成專案,無意間發現發現有個東西叫django-celery,比celery的配置更加的簡單,這裡分享一下。
首先需要統一一下使用的環境,以為如果redis的版本過高會報錯
推薦版本
Django == 2.2.6
django-celery == 3.3.1
django-redis == 4.11.0
redis == 2.10.6
celery == 3.1.26.post2
配置settings.py
因為本機直接有redis,在這裡我們直接使用redis作為我們的broker。當然,如果你追求穩定性和效率,也可使使用rabbitMQ或者kafka。
#settings.py
import djcelery djcelery.setup_loader() BROKER_URL = 'redis://127.0.0.1:6379/2' INSTALLED_APPS = [ ... "djcelery", ... ]
建立Celery所需的資料表
python manage.py migrate #如若不成功可以嘗試一下命令語句 #python manage.py syncdb
建立task
在app裡建立tasks.py檔案來寫入需要執行的非同步任務
a、當settings.py中的djcelery.setup_loader()執行時, Celery便會檢視所有INSTALLED_APPS中app目錄中的tasks.py檔案, 找到標記為task的function, 並將它們註冊為celery task.
b、在執行djcelery.setup_loader()時, task是以INSTALLED_APPS中的app名, 加.tasks.function_name註冊的
c、一次需要注意 在impprt task時, 需要保持一致
d、如果我們由於python path不同而使用不同的引用方式時(例如在tasks.py中使用from myproject.myapp.tasks import add形式), Celery將無法得知這是同一task, 因此可能會引起奇怪的bug。讓任務變成非同步
例如我們希望在使用者發出request後非同步執行該task, 馬上返回response, 從而不阻塞該request, 使使用者有一個流暢的訪問過程. 那麼, 我們可以使用.delay。
# -*- coding: utf-8 -*- from aliyunsdkcore.client import AcsClient from aliyunsdkcore.request import CommonRequest from syl.settings import ALY_ACCESSKEY_ID,ALY_ACCESSKEY_SECRET import json,time from celery import task @task def send_sms(phone,data): client = AcsClient(ALY_ACCESSKEY_ID, ALY_ACCESSKEY_SECRET, 'cn-hangzhou') request = CommonRequest() request.set_accept_format('json') request.set_domain('dysmsapi.aliyuncs.com') request.set_method('POST') request.set_protocol_type('https') # https | http request.set_version('2017-05-25') request.set_action_name('SendSms') request.add_query_param('RegionId', "cn-hangzhou") request.add_query_param('PhoneNumbers',phone) request.add_query_param('SignName', "美多商城") request.add_query_param('TemplateCode', "SMS_205402983") request.add_query_param('TemplateParam',data) response1 = client.do_action(request) # python2: print(response) print(str(response1, encoding='utf-8')) res = json.loads(str(response1,encoding='utf-8')) time.sleep(5)verifications/tasks.py
啟動celery
首先正常啟動你的django任務,然後啟動celery服務即可。python manage.py celery worker --loglevel=info
如果報錯不讓超級管理員來啟動,在settings.py加入以下配置
from celery import Celery, platforms platforms.C_FORCE_ROOT = True
驗證celery任務
在搞定上面的東西以後,你就可以通過postman來請求介面讓介面使用celery來非同步執行任務而不阻塞你的request請求。
注意
celery與3.7版本相容問題
在 celery 官方的提議下,建議將 async 檔案的檔名改成 asynchronous
Python37\Lib\site-packages\kombu\async
需要修改的檔案
Python37\Lib\site-packages\celery\utils\timer2.py
Python37\lib\site-packages\celery\concurrency\asynpool.py
Python37\lib\site-packages\celery\worker\components.py
Python37\lib\site-packages\celery\worker\autoscale.py
Python37\lib\site-packages\celery\worker\consumer.py