celery任務調度框架實踐

celery任務調度框架實踐


celery架構圖:

  1. Celery Beat:任務調度器,Beat進程會讀取配置文件的內容,週期性地將配置中到期需要執行的任務發送給任務隊列。

  2. Celery Worker:執行任務的消費者,通常會在多臺服務器運行多個消費者來提高執行效率。

  3. Broker:消息代理,或者叫作消息中間件,接受任務生產者發送過來的任務消息,存進隊列再按序分發給任務消費方(通常是消息隊列或者數據庫)。

  4. Producer:調用了Celery提供的API、函數或者裝飾器而產生任務並交給任務隊列處理的都是任務生產者。

  5. Result Backend:任務處理完後保存狀態信息和結果,以供查詢。Celery默認已支持Redis、RabbitMQ、MongoDB、Django ORM、SQLAlchemy等方式。


初始化:

1.運行celery

mac環境下的celery一下載就能直接運行。
但是centos6.9 環境下好像下載之後並不能直接運行,估計是環境變量沒有配好。
需要加上celery的安裝路徑。
使用/usr/local/bin/celery -A your_app worker --loglevel=info


2.以守護進程運行celery:

需要一個初始化腳本:celeryd

  • 使用方法:/etc/init.d/celeryd {start|stop|restart|status}

  • 配置文件:/etc/default/celeryd

參考:


3.使用redis:

mac下安裝redis

  • brew install redis
  • 如果需要後臺運行 redis 服務,使用命令 brew services start redis
  • 如果不需要後臺服務,則使用命令 redis-server /usr/local/etc/redis.conf。
  • mac os 安裝 redis

安裝redis後,啓動時指定配置文件

  • redis-server ./redis.conf

檢測後臺進程是否存在

  • ps -ef |grep redis

使用分佈式時,其他worker機子無法訪問redis去取任務:


celery基本操作命令:

參考:


celery worker:

1.啓動worker:

  • export PYTHONOPTIMIZE=1 && /usr/local/bin/celery -A your_app worker --loglevel=debug --workdir=/your_dir/your_dir/your_dir/

2.停止worker:

ps auxww | grep 'celery worker' | awk '{print $2}' | xargs kill -9


3.在celery中使用多進程:

我用的是from multiprocessing import Pool來實現多進程。
但是在運行過程中會直接報出這個錯誤
AssertionError: daemonic processes are not allowed to have children

解決方法:

  • 重寫一個Mypoolhttps://stackoverflow.com/questions/6974695/python-process-pool-non-daemonic

  • 設置環境變量
    export PYTHONOPTIMIZE=1

由於過段時間就會失效。。所以每次啓動worker的時候的時候:
export PYTHONOPTIMIZE=1 && /usr/local/bin/celery -A your_app worker --loglevel=debug --workdir=/your_dir/your_dir/your_dir/

以下 的方法沒試過:

there are two method to solve this problem ,disable assert:
1.where celery starts set export PYTHONOPTIMIZE=1 OR start celery with this parameter -O OPTIMIZATION
2.disable python packet multiprocessing process.py line 102:
assert not _current_process._config.get(‘daemon’), \ ‘daemonic processes are not allowed to have children’


4.調用worker、添加任務:

delay()和apply_async()

我們之前調用任務使用了”delay()”方法,它其實是對”apply_async()”方法的封裝,使得你只要傳入任務所需的參數即可。對於特殊的任務調度需求,你需要使用”apply_async()”,其常用的參數有:

  • countdown: 指定多少秒後任務才被執行
  • eta: 指定任務被調度的時間,參數類型是datetime
  • expires: 任務過期時間,參數類型可以是int(秒),也可以是datetime
  • retry: 任務發送失敗的重試次數
  • priority: 任務優先級,範圍是0-9
  • serializer: 參數和返回值的序列化方式

celery beat 定時任務

一個時間的Bug:

  • 當前使用pip安裝的celery,默認是安裝的最新版本4.1.0,但是在這個版本中在獲取當前時間的邏輯中存在bug,會導致定時任務配置後並不能在指定的時間被執行
  • 回退版本 到4.0.2才行
  • celery 4.1.0 版本定時任務執行時間 bug

另一種可行但麻煩的思路:

celery的定時任務會有一定時間的延遲。比如,我規定模擬登陸新浪微博任務每隔10個小時執行一次,那麼定時任務第一次執行就會在開啓定時任務之後的10個小時後纔會執行。而我抓取微博需要馬上執行,需要帶上cookie,所以不能等那1個小時。這個沒有一個比較好的解決方法,可以使用celery的crontab()來代替schdule做定時,它會在啓動的時候就執行。我採用的方法是第一次手動執行該任務,然後再通過schedule執行。


使用命令:

進入到對應your_app對應的目錄下:cd /your_dir/your_dir/your_dir
再執行:/usr/local/bin/celery -A your_app beat -l info

最方便的是,在命令中指定工作目錄,一條命令即可:

/usr/local/bin/celery -A your_dir beat -l info --workdir=/your_dir/your_dir/your_dir/


定時任務參數參考表:


動態管理定時任務:

查過挺多資料,有兩種解決方法。跟celery運行的調度器(schedule)息息相關的。

  • 使用第三方schedule:
    如django-celery-beat庫會將定時任務的規則存入到數據庫中,而不用通過配置文件來定義。

try to install django-celery instead of django-celery-beat. django-celery works with Celery 3 (unlike django-celery-beat). You can then, for example import PeriodicTask from djcelery.models instead of from django_celery_beat.models . This allows you to add/delete/manipulate tasks both dynamically AND PROGRAMMATICALLY (not only from the Django admin site). The drawback to this workaround is that if one doesn’t need django-celery for anything other than this, then it bloats one’s app. Thus, It would be better to have Celery 4.0 included in cookiecutter-django so that django-celery-beat models can be used

【celery進階】定時任務和優先級

  • 使用框架默認schedule

我使用的是這一種方法。
只能管理celery的配置文件了,每次增加或減少定時任務的時候,都要對配置文件進行相應的修改。
每次修改完都要重啓celerybeat,試過多種方法,發現用supervisor來管理celery beat的進程是比較好的。


管理celery beat進程

用supervisor來管理celery beat進程。

  • 安裝:pip install supervisor

  • Supervisor配置

    • /usr/local/bin/echo_supervisord_conf > /etc/supervisord.conf
  • 操作:

    • 開啓:supervisord -c /etc/supervisord.conf
    • 重啓:supervisorctl -c /etc/supervisord.conf reload
    • 關閉:supervisorctl -c /etc/supervisord.conf shutdown

other:

分佈式:


隊列:


flower:

圖形化管理celery界面:

/usr/local/bin/celery -A celery_app flower --port=5555


參考:

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