Django應用celery,實現多worker,多隊列

一、原理

celery是一個分佈式的任務調度模塊,那麼怎麼實現它的分佈式功能呢,celery可以支持多臺不同的計算機執行不同的任務或者相同的任務。

簡單理解:

可以有多個"消息隊列"(message Queue),不同的消息可以指定發送給不同的Message Queue,

而這是通過Exchange來實現的,發送消息到"消息隊列"中時,可以指定routiing_key,Exchange通過routing_key來吧消息路由(routes)到不同的"消息隊列"中去。

 

 

exchange 對應 一個消息隊列(queue),即:通過"消息路由"的機制使exchange對應queue,每個queue對應每個worker。

二、實例目錄結構

 

三、案例實現

1. 簡單介紹目錄結構

首先創建一個django項目,創建一個app測試用。

在app的同級目錄下創建關於celery的一個目錄(celery_tasks),在celery_tasks創建一個config.py文件用來放配置文件,創建一個main.py文件,即爲入口、配置加載文件。並在同級目錄下創建一個/多個app(比如放送郵件,發送短信等模塊,),然後在此app下創建存放異步任務代碼的tasks.py文件,目錄機構如上圖。

2. main.py文件介紹如註釋

from celery import Celery

 

import os

 

# 爲celery使用django配置文件進行設置

if not os.getenv('DJANGO_SETTINGS_MODULE'):

    os.environ['DJANGO_SETTINGS_MODULE'] = 'amirtestcelery.settings'

# 創建celery應用

app = Celery('amirtestcelery')

# 導入celery配置文件

app.config_from_object('celery_tasks.config')

# 自動註冊celery任務,需要啓動哪個模塊下,則加入列表中

app.autodiscover_tasks(['celery_tasks.appone', 'celery_tasks.apptwo'])

 

3. 分別在tasks.py文件下創建異步任務

 

 

 

這裏提醒的是 @app.task(name='apptwo_mult')   這裏的name是爲這個方法提供一個命名空間(唯一),後面會用到

4. config.py文件介紹(關鍵)

import datetime

from celery.schedules import crontab

from kombu import Exchange, Queue

 

BROKER_URL = 'redis://localhost:6379/10'

CELERY_RESULT_BACKEND = 'redis://localhost:6379/11'

CELERY_TIMEZONE = 'Asia/Shanghai'

 

# 隊列

CELERY_QUEUES = (

    Queue("default", Exchange("default"), routing_key="default"),

    Queue("appone_add_queue", Exchange("appone_add_queue"), routing_key="appone_add_router"),

    Queue("apptwo_mult_queue", Exchange("apptwo_mult_queue"), routing_key="apptwo_mult_router")

)

# 路由

CELERY_ROUTES = {

    'appone_add': {"queue": "appone_add_queue", "routing_key": "appone_add_router"},

    'apptwo_mult': {"queue": "apptwo_mult_queue", "routing_key": "apptwo_mult_router"}

}

 

# 定時任務配置如下

CELERYBEAT_SCHEDULE = {

    'beat_task1': {

        'task': 'appthree_comment',

        'schedule': datetime.timedelta(seconds=2),

        'args': (2, 8)

    },

    'beat_task2': {

        'task': 'appthree_comment',

        'schedule': crontab(hour=16, minute=32),

        'args': (4, 5)

    }

}

 

# 單獨對一個任務啓動命令 會啓動指定queue

# celery -A celery_tasks.main  worker -l info -n workerA.%h -Q appone_add_queue

# celery -A celery_tasks.main  worker -l info -n workerB.%h -Q apptwo_mult_queue

 

# 當任務沒有指定queue 則任務會加入default 隊列 beat(定時任務也會加入default隊列)

# celery -A celery_tasks.main  worker -l info -n worker -Q celery

 

# 啓動定時任務

# celery beat -A celery_tasks.main -l INFO

 

 

# -A 表示 應用目錄  這裏是celery_tasks.main

# -B 表示 定時任務

# -l 表示日誌級別

# -n woker名

# -Q 隊列名

# .%h 對應不同主機ip  如果默認localhost,所以可以省略.%h

 

BROKER_URL 表示生產者存放任務的數據庫,我這用的是redis

CELERY_RESULT_BACKEND  表示消費者存放的結果

CELERY_TIMEZONE   設置時區唄

CELERY_QUEUES 創建隊列

 

 

 

 

 

5. 啓動命令(代碼都寫好了,是時候啓動了)

# 單獨對一個任務啓動命令 會啓動指定queue

# celery -A celery_tasks.main  worker -l info -n workerA.%h -Q appone_add_queue

# celery -A celery_tasks.main  worker -l info -n workerB.%h -Q apptwo_mult_queue

 

# 當任務沒有指定queue 則任務會加入default 隊列 beat(定時任務也會加入default隊列)

# celery -A celery_tasks.main  worker -l info -n worker -Q celery

 

# 啓動定時任務

# celery beat -A celery_tasks.main -l INFO

 

 

# -A 表示 應用目錄  這裏是celery_tasks.main

# -B 表示 定時任務

# -l 表示日誌級別 這是英文小寫l不是數字1

# -n woker名 自定義

# -Q 隊列名

# .%h 對應不同主機ip  如果默認localhost,所以可以省略.%h

6. 隨筆

Celery是典型的生產者與消費者模式,生產者(broker)add任務到隊列中,消費者(worker)去隊列中BROKER_URL拿任務,執行完之後,結果放CELERY_RESULT_BACKEND中。創建多個隊列之後,啓動多個worker,每個worker啓動一個主進程,每個主進程還可以創建多個子進程,當然可以通過CELERY_CONCURRENCY設置子進程個數,也就是併發數。

我是Amir,有興趣探討的可以聯繫我QQ:429771087

Git:[email protected]:AmirHuang/amirtestcelery.git

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