djcelery的定時任務問題


    前幾天在工作中遇到djcelery定時任務失效的問題,查了好幾天,最終定位解決,整理分享下

    首先簡單介紹下djcelery定時任務的框架,估計了解它的人都很熟悉,如下圖

    其實簡單的說就是celery的beat定時將任務發給消息中間件(這里用的是rabbitmq隊列),rabbitmq將定時任務發送給celery worker去執行(即django中的task),最終將檢測結果存儲的過程。

    關於celery的詳細介紹可見http://python.jobbole.com/87086/

    問題現象如下:

    發現一直正常運行的定時任務沒有正常執行,而celery的worker和beat進程都在后台運行中,即如下的進程是存在的

    故曾經的運維經驗告訴我要重啟,所以,第一招,重啟celery的worker和beat進程,但發現問題依舊,也就是說這個問題沒法通過守護進程的方式避免。

    那第二招就是看日志了,查看worker的日志,發現其實worker已經准備好,但一直沒有真正去執行任務

    下一步就是查看發生任務的消息中間件了,就是神奇的rabbitmq,rabbitmq的情況可在網頁查看,如下圖

    可以明顯的看到queue message是沒有數據的,但message rates卻是有數據的(這個點其實還是沒弄清到底是為什么,歡迎比較懂的同學指點)

    故嘗試手動執行celery beat和worker,rabbitmq是否能收到任務,發現在djcelery的任務沒有發送到rabbitmq中,手動編寫測試task程序

celeryconfig.py

import sys
import os
sys.path.insert(0, os.getcwd())

CELERY_IMPORTS = ("tasks", )

CELERY_RESULT_BACKEND = "amqp"

BROKER_HOST = "localhost"
BROKER_PORT = 5672
BROKER_USER = "guest"
BROKER_PASSWORD = "guest"
BROKER_VHOST = "/"

tasks.py

from celery.task import task
from celery import Celery, platforms

platforms.C_FORCE_ROOT = True
@task
def add(x, y):
    return x + y
                  

    執行任務,發現rabbitmq可以接受到消息,由於之前對隊列的了解相當少,這里也請教了些對隊列比較了解的同學,都覺得應該是消費者配置的問題,但查了django的setting沒看到異常。

    查了下網上關於rabbitmq的資料,大概是生產者通過exchange將消息按照規則發送給對應的隊列,而我們的隊列是沒有收到消息的,修改了exchange規則調試,確實隊列中會收到消息,但這個隊列不是我們系統制定的隊列。

    在和rabbitmq糾纏了好久后,各種執行celery的命令,發現手動單獨執行celery beat時會出現如下報錯

    懷疑與定時任務有關,查看了報錯的celery的schedules.py文件中報錯的位置,初步判斷是定時任務設定的問題,通過django的admin查看Periodic task的任務設置情況,發現有一個測試任務沒有設置crontab和Interval,之前就遇到過當進入到這個頁面,如果兩個都不設置報錯就會報錯的情況,故將interval改為定時監測時間,crontab不設置后,celery worker日志中有數據了,rabbitmq的隊列也恢復正常了。

 

    其實這個問題在這個文檔中有一些說明

https://my.oschina.net/kinegratii/blog/292395?fromerr=2lvw3H0L

    定時任務的重點在於必須有且僅有interval和crontab中的其一設置,即不能同時設置也不能同時不設置

    celery很強大,更多的情況可直接參考上述的兩個文檔,基本夠用了

    而為什么會出現測試任務的定時設置的crontab和interval都為空的情況呢?由於我們的系統使用的開源項目為頁面式的,在調試新功能時增加的測試任務,而修改沒有涉及到后續任務執行情況的改動,故沒有在admin頁面設定interval和crontab,導致celery beat啟動報錯。

    為了避免這類的問題再次出現,進行如下的一些改進

    1、在系統頁面中增加添加任務后自動設置默認的crontab和interval(省得人工去django的admin改,當然,django的admin很強大)

    2、增加celery beat單獨的日志

 

    最后,無變更不故障,這句話我是真的體會到了

 

 

 

 

   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM