python web開發筆記--celery

在做網站後端開發時,會經常碰到這樣類似的需求:用戶需要在我們的網站填寫註冊信息,我們發給用戶一封註冊激活郵件到用戶郵箱,由於某種原因,導致客戶端需要等待比較久的時間纔會有響應,這種體驗非常不好:

在這裏插入圖片描述

  • 之前想的是用多線程來解決,但是有可能會出現會幾個問題:
    1.併發比較大的時候,線程切換會有開銷時間;
    2.假如使用線程池會限制併發的數量;
    3.多線程間的數據共享維護比較麻煩;

如果有東西能實現一下兩點呢:

  • 將耗時任務放到後臺異步執行,不會影響用戶其他操作。
  • 還可以實現定時處理某些任務。

就像中介一樣,本來你需要親自去辦理業務,然後在那裏先排隊,輪到你了才能辦理業務,如果人很多,你就要等很久,幹不了其他事。這時候如果你找中介,你就只用把事情交代清楚給中介,你就能去幹下一件事情了,中介幫你幹活,幹好了就告訴你。

後來就自己找資料,發現有個celery蠻符合需求。
  Celery(功能完備即插即用的任務隊列)是一個用於執行異步任務的框架,它能很容易就能將Web應用中的一些耗時的作業轉交給工作池,讓工作池中的worker以異步的方式執行這些作業。且不會影響用戶其他操作。
  它可以讓任務的執行同主程序完全脫離,甚至不在同一臺主機內。它通過隊列來調度任務,不用擔心併發量高時系統負載過大。它可以用來處理複雜系統性能問題,卻又相當靈活易用。
  任務隊列中包含稱作任務的工作單元。有專門的工作進程持續不斷的監視任務隊列,並從中獲得新的任務並處理。
  celery通過消息進行通信,通常使用一個叫Broker(中間人)來協client(任務的發出者)和worker(任務的處理者)。 clients發出消息到隊列中,broker將隊列中的信息派發給worker來處理。

一個celery系統可以包含很多的worker和broker,可增強橫向擴展性和高可用性能。

在這裏插入圖片描述
從圖上可以看出Celery包含幾個模塊:

  • 任務模塊
    主要包異步任務和定時任務,異步任務通常在業務邏輯中被觸發併發送到任務隊列中,而定時任務是由Celery Beat進程週期性的將任務發往任務隊列。
  • 消息中間件Broker
    Broker就是任務調度隊列,接受任務生產者發送來的消息,將任務存入隊列,之所以需要中間人的原因是Celrey本身是不提供消息隊列的服務,所以需要第三方組件實現(redis)。
  • 任務執行單元Worker
    Worker是執行任務的單元,它實時監控消息隊列,如果有任務就獲取任務並執行它。
  • 任務存儲Backend
    Backend用於存儲任務只想的結果,存儲可以使用RabbitMQ或者Redis或者數據庫等。

官方支持的Broker列表如下
在這裏插入圖片描述
PS:我自己測試Celery的時候,Broker和Backend配置的都是redis。

這裏提一下,Celery支持多線程,且有幾種模式,只不過需要自己去設置,默認是自己CPU的線程數。

  • 建議單獨設置一個需要用Celery文件夾,放在工程目錄下,tasks文件夾就是我單獨設置的。關於Celery主要的文件有兩個,main.py和config.py。main.py做啓動文件,config.py是配置文件,protask目錄下的tasks.py是你需要放入隊列中去運行的耗時任務,可以根據需要創建不同的tasks.py文件。

下面做一個簡單的Celery例子
在這裏插入圖片描述

  • config.py
# coding=utf-8

#Broker和Backend,按自己實際選着的去配置,這裏只是演示。
#Celery有很多配置選項能夠使得celery能夠符合我們的需要,但是默認的幾項配置已經足夠應付大多數應用場景了。

BROKER_URL = "redis://127.0.0.1:6379/1"
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/2'
  • main.py
# coding=utf-8

#這裏只做演示

from celery import Celery
from YouProjectName.tasks import config


# 定義celery對象
celery_app = Celery("projectname")

# 引入配置信息
celery_app.config_from_object(config)

# 自動搜尋異步任務
celery_app.autodiscover_tasks(["YouProjectName.tasks.protask"])
  • tasks.py
# coding=utf-8

#把耗時間的任務從業務邏輯中剝離出來,寫到tasks.py中,在業務邏輯中 import 你的tasks
#調用一下tasks中你寫的就行了,如my_task1()

from YouProjectName.tasks.main import celery_app

# 創建任務函數
@celery_app.task
def my_task1():
    print("任務函數(my_task1)正在執行....")

@celery_app.task
def my_task2():
    print("任務函數(my_task2)正在執行....")

@celery_app.task
def my_task3():
    print("任務函數(my_task3)正在執行....")
#proj換成你的main路徑
celery -A proj worker -l info

Celery需要單獨啓動,啓動方式和附帶參數可以參考官方文檔:

啓動成功後的界面

在這裏插入圖片描述

參考文檔:

如有侵權,請聯繫我!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章