1. 程式人生 > >Django框架中,使用celery實現非同步

Django框架中,使用celery實現非同步

作用:在使用框架時,在檢視函式中實現非同步
構成:
任務task:一段耗時並與響應結果無關的程式碼,如發簡訊
工人worker:新程序,用於執行任務程式碼
代理人broker:呼叫任務時,將任務新增到佇列中,通知worker執行
佇列queue:用於儲存待執行的任務

呼叫:任務函式.delay(引數)

說明:定義任務函式的檔案tasks.py,檔名是固定的
實現步驟:
1.在專案目錄下,新建包celery_tasks用於儲存celery非同步任務
2.在celery_tasks包下新建config.py,指定代理人,用於儲存celery的配置資訊

# 指定使用redis作為代理人,將來,redis會儲存待執行任務佇列
broker_url = 'redis://127.0.0.1:6379/14'

3.在celery_tasks包下新建main.py,建立celery物件,配置自動識別任務,用於作為celery的啟動檔案

from celery import Celery

# 為celery使用django配置檔案進行設定
import os
os.environ['DJANGO_SETTINGS_MODULE'] = '(專案settings地址)'

# 建立celery應用,Celery(‘名字可隨意’)
app = Celery('taobao')

# 匯入celery配置
app.config_from_object('celery_tasks.config')

# 自動註冊celery任務
app.autodiscover_tasks([
    'celery_tasks.sms_code',
]) 

4.在celery_tasks新建包,如sms_code

5.在celery_tasks/sms_code/下建立tasks.py,用於儲存傳送簡訊的非同步任務
6.定義方法,封裝耗時程式碼,新增裝飾器

from celery_tasks.main import app

@app.task(name='send_sms_code')
def send_sms_code(code):
    # 定義方法,封裝耗時程式碼
    print(code)

7.在main.py中註冊
8.啟動工人,如果程式碼發生改變,需要重啟任務
9.在檢視函式中呼叫verifications/views.py:任務方法.delay(引數)(這裡沒有呼叫第三方介面發簡訊,只是打印出驗證碼)

  

class SmsView(APIView):
    # 接收手機號,發簡訊
    def get(self, request, mobile):
        # 連線redis,指定cache中的鍵
        redis_cli = get_redis_connection('sms_code')

        # 1.驗證是否向此手機號發過簡訊,如果發過則返回提示
        if redis_cli.get('sms_flag_' + mobile):
            return Response({'message': '已經發送'})

        # 2.如果未發過,則發簡訊
        # 2.1生成隨機6位數
        sms_code = random.randint(100000, 999999)

        # 優化,只與redis互動一次
        redis_pipeline = redis_cli.pipeline()
        redis_pipeline.setex('sms_' + mobile, constants.SMS_CODE_EXPIRES, sms_code)
        redis_pipeline.setex('sms_flag_' + mobile, constants.SMS_FLAG_EXPIRES, 1)
        redis_pipeline.execute()

        # 2.4發簡訊,可以呼叫第三方簡訊平臺發簡訊
        # print(sms_code)
        send_sms_code.delay(sms_code)

        # 3.響應
        return Response({'message': 'OK'})

  

10.啟動celery服務

執行命令

celery -A celery_tasks.main worker -l info