Django使用Celery非同步任務隊列,djangocelery

來源:互聯網
上載者:User

Django使用Celery非同步任務隊列,djangocelery
1  Celery簡介

Celery是非同步任務隊列,可以獨立於主進程運行,在主進程退出後,也不影響隊列中的任務執行。

任務執行異常退出,重新啟動後,會繼續執行隊列中的其他任務,同時可以緩衝停止期間接收的工作任務,這個功能依賴於訊息佇列(MQ、Redis)。

 

1.1  Celery原理

 

 

Celery的架構由三部分組成,訊息中介軟體(message broker),任務執行單元(worker)和任務執行結果儲存(task result store)組成。

  • 訊息中介軟體:Celery本身不提供Message Service,但是可以方便的和第三方提供的訊息中介軟體整合。包括,RabbitMQRedis, MongoDB (experimental), Amazon SQS (experimental),CouchDB (experimental), SQLAlchemy (experimental),Django ORM (experimental), IronMQ。推薦使用:RabbitMQ、Redis作為訊息佇列。
  • 任務執行單元:Worker是Celery提供的任務執行的單元,worker並發的運行在分布式的系統節點中。
  • 任務結果儲存:Task result store用來儲存Worker執行的任務的結果,Celery支援以不同方式儲存任務的結果,包括AMQP, Redis,memcached, MongoDB,SQLAlchemy, Django ORM,Apache Cassandra, IronCache
1.2     Celery適用情境
  • 非同步任務處理:例如給註冊使用者發送短訊息或者確認郵件任務。
  • 大型任務:執行時間較長的任務,例如視頻和圖片處理,添加浮水印和轉碼等,需要執行任務時間長。
  • 定時執行的任務:支援任務的定時執行和設定時間執行。例如效能壓測定時執行。

 

2      Celery開發環境準備2.1     環境準備

軟體名稱

版本號碼

說明

Linux

Centos 6.5(64bit)

作業系統

Python

3.5.2

 

Django

1.10

Web架構

Celery

4.0.2

非同步任務隊列

Redis

2.4

訊息佇列

 

2.2     Celery安裝

使用方法介紹:

Celery的運行依賴訊息佇列,使用時需要安裝redis或者rabbit。

這裡我們使用Redis。安裝redis庫:

sudo yum install redis

  

啟動redis:

sudo service redis start

 

安裝celery庫

sudo pip install celery==4.0.2

 

3      Celery單獨執行任務3.1     編寫任務

建立task.py檔案

說明:這裡初始Celery執行個體時就載入了配置,使用的redis作為訊息佇列和儲存任務結果。

 

 

運行celery:

$ celery -A task worker --loglevel=info

看到下面的列印,說明celery成功運行。

 

3.2     調用任務

 直接開啟python互動命令列

 執行下面代碼:

 

可以celery的視窗看到任務的執行資訊

 

 

任務執行狀態監控和擷取結果:

 

 

 

3.3     任務調用方法總結

有兩種方法:

delay和apply_async ,delay方法是apply_async簡化版。

add.delay(2, 2)add.apply_async((2, 2))add.apply_async((2, 2), queue='lopri')

 

delay方法是apply_async簡化版本。

apply_async方法是可以帶非常多的配置參數,包括指定隊列等

  • Queue 指定隊列名稱,可以把不同任務分配到不同的隊列

 

3.4     任務狀態

每個任務有三種狀態:

PENDING -> STARTED -> SUCCESS

 

任務查詢狀態:

res.state

 

來查詢任務的狀態

 

 

4      與Django整合

上面簡單介紹了celery非同步任務的基本方法,結合我們實際的應用,我們需要與Django一起使用,下面介紹如何與Django結合。

4.1     與Django整合方法

與Django整合有兩種方法:

  • Django 1.8 以上版本:與Celery 4.0版本整合
  • Django 1.8 以下版本:與Celery3.1版本整合,使用django-celery庫

 

今天我們介紹celery4.0 和django 1.8以上版本整合方法。

4.2     建立專案檔

建立一個項目:名字叫做proj

- proj/  - proj/__init__.py  - proj/settings.py  - proj/urls.py  - proj/wsgi.py- manage.py

 

建立一個新的檔案:proj/proj/mycelery.py

from __future__ import absolute_import, unicode_literalsimport osfrom celery import Celery # set the default Django settings module for the 'celery' program.os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings') app = Celery('proj') # Using a string here means the worker don't have to serialize# the configuration object to child processes.# - namespace='CELERY' means all celery-related configuration keys#   should have a `CELERY_` prefix.app.config_from_object('django.conf:settings', namespace='CELERY') # Load task modules from all registered Django app configs.app.autodiscover_tasks()

 

在proj/proj/__init__.py:添加

from __future__ import absolute_import, unicode_literals # This will make sure the app is always imported when# Django starts so that shared_task will use this app.from .mycelery import app as celery_app __all__ = ['celery_app']

 

4.3     配置Celery

我們在mycelery.py檔案中說明celery的設定檔在settings.py中,並且是以CELERY開頭。

   
app.config_from_object('django.conf:settings', namespace='CELERY')

 

在settings.py檔案中添加celery配置:

 

 

我們的配置是使用redis作為訊息佇列,訊息的代理和結果都是用redis,任務的序列化使用json格式。

重要:redis://127.0.0.1:6379/0這個說明使用的redis的0號隊列,如果有多個celery任務都使用同一個隊列,則會造成任務混亂。最好是celery執行個體單獨使用一個隊列。

4.4     建立APP

建立Django的App,名稱為celery_task,在app目錄下建立tasks.py檔案。

完成後目錄結構為:

├── celery_task│   ├── admin.py│   ├── apps.py│   ├── __init__.py│   ├── migrations│   │   └── __init__.py│   ├── models.py│   ├── tasks.py│   ├── tests.py│   └── views.py├── db.sqlite3├── manage.py├── proj│   ├── celery.py│   ├── __init__.py│   ├── settings.py│   ├── urls.py│   └── wsgi.py└── templates

 

4.5     編寫task任務

編輯任務檔案

tasks.py

在tasks.py檔案中添加下面代碼

# Create your tasks herefrom __future__ import absolute_import, unicode_literalsfrom celery import shared_task
@shared_taskdef add(x, y): return x + y @shared_taskdef mul(x, y): return x * y @shared_taskdef xsum(numbers): return sum(numbers)

 

啟動celery:

celery -A proj.mycelery worker -l info

 

說明:proj為模組名稱,mycelery為celery的執行個體所在的檔案。

啟動成功列印:

 

 

4.6     在views中調用任務

在views中編寫介面,實現兩個功能:

  • 觸發任務,然後返回任務的結果和任務ID
  • 根據任務ID查詢任務狀態

代碼如下:

 

 

啟動django。

新開一個會話啟動celery;啟動命令為:

celery –A proj.mycelery worker –l info

 

訪問http://127.0.0.1:8000/add,可以看到返回的結果。

 

 

在celery啟動並執行頁面,可以看到下面輸出:

 

 

4.7     在views中查詢任務狀態

有的時候任務執行時間較長,需要查詢任務是否執行完成,可以根據任務的id來查詢任務狀態,根據狀態進行下一步操作。

可以看到任務的狀態為:SUCCESS

 

 

5      Celery定時任務

Celery作為非同步任務隊列,我們可以按照我們設定的時間,定時的執行一些任務,例如每日Database Backup,日誌轉存等。

Celery的定時任務配置非常簡單:

定時任務的配置依然在setting.py檔案中。

說明:如果覺得celery的資料設定檔和Django的都在setting.py一個檔案中不方便,可以分拆出來,只需要在mycelery.py的檔案中指明即可。

app.config_from_object('django.conf:yoursettingsfile', namespace='CELERY')

 

 

5.1     任務間隔運行
#每30秒調用task.addfrom datetime import timedeltaCELERY_BEAT_SCHEDULE = {    'add-every-30-seconds': {        'task': 'tasks.add',        'schedule': timedelta(seconds=30),        'args': (16, 16)    },}

 

5.2     定時執行

定時每天早上7:30分運行。

注意:設定任務時間時注意時間格式,UTC時間或者本地時間。

#crontab任務#每天7:30調用task.addfrom celery.schedules import crontabCELERY_BEAT_SCHEDULE = {    # Executes every Monday morning at 7:30 A.M    'add-every-monday-morning': {        'task': 'tasks.add',        'schedule': crontab(hour=7, minute=30),        'args': (16, 16),    },}

 

5.3     定時任務啟動

配置了定時任務,除了worker進程外,還需要啟動一個beat進程。

Beat進程的作用就相當於一個定時任務,根據配置來執行對應的任務。

5.3.1  啟動beat進程

命令如下:

celery -A proj.mycelery beat -l info

 

 

5.3.2  啟動worker進程

Worker進程啟動和前面啟動命令一樣。

 

celery –A proj.mycelery worker –l info

 

6      Celery深入

Celery任務支援多樣的運行模式:

  • 支援動態指定並發數 --autoscale=10,3 (always keep 3 processes, but grow to 10 if necessary).
  • 支援鏈式任務
  • 支援Group任務
  • 支援任務不同優先順序
  • 支援指定任務隊列
  • 支援使用eventlet模式運行worker

例如:指定並發數為1000

celery -A proj.mycelery worker -c 1000

 

這些可以根據使用的深入自行瞭解和學習。

 

 

7      參考資料

Celery官網:

http://docs.celeryproject.org/en/latest/index.html

Celery與Django:

http://docs.celeryproject.org/en/latest/getting-started/next-steps.html#next-steps

celery定時任務:

http://blog.csdn.net/sicofield/article/details/50937338

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.