簡單介紹:
說明: 此模塊是一個專注於分佈式消息傳遞的異步任務隊列,所謂任務就是消息,消息中的有效載荷中包含要執行的任務需要的全部數據
幾大特性:
1. Celery易於使用和維護,且不需要配置文件,默認配置啓動時自動寫入消息代理.
2. Celery高可用,連接丟失或失敗時客戶端或消費者會自動重試,並且可通過消息代理的雙主/主從模式來提高高可用性
3. Celery快速,單個進程每分鐘可處理百萬任務,且優化後可保持往返延遲在亞毫秒級別
4. Celery靈活,幾乎所有部分都支持擴展或單獨使用,連接池,序列化,壓縮模式,日誌,調度器,消費者,生產者,自動擴展,中間人傳輸等
5. Celery消息代理完美支持RabbitMQ和Redis,其它實驗性支持,結果存儲完美支持AMQP/Redis/Memcached/MongoDB/SQLAlchemy/DjangoORM/Apache Cassandra,序列化完美支持Pickle/Json/Yaml/Msgpack/Zlib/Bzip2,併發模式完美支持Prefork/Eventlet/Gevent/Worker.
常用架構:
說明: 任務生產者通過Celery API將需要執行的任務丟到一個消息代理的消息隊列中,然後由任務消費者根據自身情況從消息隊列中獲取任務執行,可將它們執行後結果存儲,任務發佈者/任務消費者是分開運行從而達到異步效果,但是需要注意的是消息代理並不屬於Celery組件,官方目前完全支持的有RabbitMQ和Redis,但個人強烈建議RabbitMQ.
補充: 如上Producer既可以爲Celery Client也可爲Publisher,這是因爲Celery作爲分佈式消息傳遞的異步任務隊列,應用是可以靈活的部署在單臺(通過導入執行任務單元)或多臺(通過app.send_task(func, (args))實現)主機上.
方案選型:
說明: 綜上所屬,爲了提供更高的性能,強烈推薦選擇RabbitMQ做消息代理,C庫Librabbitmq做PY客戶端接口,Msgpack做客戶端與消費者消息序列化,Redis做結果存儲.
快速安裝:
PY2.6.X: pip install --upgrade "kombu==3.0.37" "celery[librabbitmq,redis,msgpack]==3.1.25" PY2.7.X: pip install --upgrade "kombu==3.0.37" "celery[librabbitmq,redis,msgpack]==3.1.25"
注意: 由於Celery3.1.25以上的版本由於官方缺乏資金而移除了相當多的功能,所以還是強烈推薦使用3.1.25這個跨平臺長期穩定支持版,目前依然支持PY2.6.X和PY2.7.X
快速上手:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2016-12-24 16:27:01 # @Author : 李滿滿 ([email protected]) # @Link : http://xmdevops.blog.51cto.com/ # @Version : $Id$ from __future__ import absolute_import # 說明: 導入公共模塊 from celery import Celery # 說明: 導入其它模塊 app = Celery( __name__, broker='amqp://root:[email protected]:5672//', backend='redis://10.2.5.51:5123/0', include=[ ], ) @app.task def add(x, y): return x + y
說明: Celery應用必須是可導入的,PY一切皆模塊,所以保存如上代碼爲app.py即可,簡單說明,Celery類的第一個參數是當前模塊名稱,而且是必須的,broker指定消息代理,backend指定結果存儲,include指定多個任務執行文件相對導入位置,然後在終端中執行celery worker -A app --loglevel=info啓動消費者,然後再啓動一個終端在PyShell中執行from app import add;
add.delay(4, 4),此時會調用任務異步返回一個AsyncResult實例,用於檢查任務狀態result.ready()/等待任務完成result.get(timeout=1, propagate=False)/獲取任務返回值,此時可以分別在兩邊終端以及結果存儲中查看變化,其它高端玩法可通過celery --help獲取.
必知必會:
說明: 命令行執行celery worker -A <app> --loglevel=info時,<app>必須可導入,所以可以爲PY模塊或包,但需要注意的不管是包還是模塊都必須正確指定Celery入口文件(如果爲包則默認的入口文件名爲celery.py)的絕對導入名稱(app/work.app),Celery通過動態導入獲取實例化後的應用,通過實例化時指定的配置以及include來依次導入任務執行文件中的任務指定單元,然後就是等待任務,可以看出Celery是通過相對/絕對導入來查找定義的任務執行單元,PY導入成功後會生成PYC文件,所以代碼修改後一定要先刪除PYC文件.