同步發(fā)表于個人站點: http://panzhixiang.cn/article/2023/3/16/68.html
一、背景介紹
我們以前一直使用k8s的cronjob來管理定時任務(wù)的。把定時任務(wù)相關(guān)的代碼單獨封裝成一個pod,然后以cronjob的方法來觸發(fā)。
雖然這個方法操作很簡單,沒有什么第三方資源的依賴(比如Redis),但是也有一個明顯的缺點。
定時任務(wù)的代碼脫離了Django代碼,也就不能使用Django的很多功能了,只能通過DRF封裝的API來跟Django的Server通信。
有的時候為了一個定時任務(wù),要封裝很多API,還要考慮鑒權(quán)等問題,也挺麻煩的,所以就在新項目中打算換一個方法來做定時任務(wù)的管理。
同時使用Python和Django的工程師估計基本都知道Celery,它是一個很好的異步任務(wù)框架。我上一次使用它還是2020年,發(fā)現(xiàn)這幾年Celery的使用方法發(fā)生了一些變化,在網(wǎng)上找了一圈也沒有找到很好的中文資料,所以自己寫一篇相關(guān)的博客,希望能給以后需要查詢相關(guān)信息的人提供一點幫助。
二、Celery配置
在配置Celery之前需要先安裝,pip install celery
, 接下來就開始配置了。
在正式開始介紹配置之前,我們需要一些假設(shè),以便下面的文字可以表述的更清楚。
我們以django-admin startproject proj
創(chuàng)建一個Django項目,Django版本應(yīng)當(dāng)>=3.0, 創(chuàng)建成功之后我們會得到如下的一個目錄結(jié)構(gòu):
proj
├── manage.py
└── proj
├── asgi.py
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
熟悉Django的人應(yīng)該對上面這個目錄樹非常熟悉,下面的內(nèi)容都是基于這個目錄樹寫的,所以需要記住這個目錄樹。
1. 定義Celery實例
為了定義Celery實例,需要在上面的目錄樹中創(chuàng)建一個文件: proj/proj/celery.py。
這個文件名是celery.py,跟settings.py在同一層目錄。
內(nèi)容如下,我把一些很重要的信息以注釋的形式寫在代碼里了,注意查看。
import os
from celery import Celery
# 這個配置可以避免在其他的tasks.py中初始化django配置,雖然不是必須的,但是強烈建議要有這個配置
os.environ.setdefault(
'DJANGO_SETTINGS_MODULE', 'proj.settings'
)
# 這個就是從環(huán)境變量中獲取redis的地址,我這里使用redis作為broker
REDIS_HOST = os.getenv('REDIS_HOST', 'localhost:6379')
app = Celery(
'proj', # 第一個參數(shù)是為celery的實例起了一個名字,這里叫做proj
backend='redis://' + REDIS_HOST + '/1',
broker='redis://' + REDIS_HOST + '/0',
)
# 可以用這個方法批量配置celery,
# 這幾個配置在一幫的場景中就足夠使用了
# 另外,其實還有幾種其他方法來配置celery,但是我覺得這個方法對于不是非常大的項目來說就足夠了。
app.conf.update(
task_serializer='json',
accept_content=['json'], # Ignore other content
result_serializer='json',
enable_utc=True,
)
# 這一行會從django的settings文件中獲取一些celery的配置
# namespace等于CELERY的意思是settings中以 “CELERY_” 開頭的配置都會被識別為celery的配置
app.config_from_object('django.conf:settings', namespace='CELERY')
# 會自動發(fā)現(xiàn)所有Django app中的任務(wù)
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print(f'Request: {self.request!r}')
除了上面這個配置,還有兩個地方需要配。
首先是需要在proj/proj/__init__.py中添加以下內(nèi)容:
from .celery import app as celery_app
__all__ = ('celery_app',)
它的作用是在啟動Django的時候自動加載celery。
還有一個就是需要在django的settings中添加celery的配置,也就是上面代碼中app.config_from_object('django.conf:settings', namespace='CELERY')
提到的部分。
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60 # 單個任務(wù)的最大運行時間,單位是秒
2. 記錄任務(wù)的結(jié)果
用celery做任務(wù)調(diào)度的時候可以最好能把每一次任務(wù)的結(jié)果記錄下來,以便以后查閱,尤其是當(dāng)任務(wù)沒有按照預(yù)期運行的時候,這一點更加重要。
官網(wǎng)推薦使用django-celery-results做記錄任務(wù)結(jié)果。
- 安裝
pip install django-celery-results
- 注冊
django-celery-results是一個單獨的django的app,所以需要在settings.py注冊一下
注冊之后還需要遷移數(shù)據(jù)庫,INSTALLED_APPS = ( ..., 'django_celery_results', )
python manage.py migrate django_celery_results
- 配置
django-celery-results只是一個幫助自動存儲任務(wù)結(jié)果的包,最終數(shù)據(jù)還需要一個地方落地,有很多地方都可以用來存儲任務(wù)結(jié)果,比如數(shù)據(jù)庫、本地文件系統(tǒng),redis等等,我這里使用數(shù)據(jù)庫,也比較推薦使用數(shù)據(jù)庫。
在django的setting.py中添加一下配置:CELERY_RESULT_BACKEND = 'django-db' # 使用數(shù)據(jù)庫做后端 CELERY_CACHE_BACKEND = 'django-cache' # 老實說,不知道這個緩存配置到底有什么作用,但是官網(wǎng)推薦使用這個配置,我也就留著了 CELERY_CACHE_BACKEND = 'default'
- 啟動
注意這個命令要在第一層proj目錄下運行,不然會報錯,提示找不到配置文件之類的錯誤celery -A backend worker --loglevel=INFO
三、定時任務(wù)配置
前面介紹了怎么樣配置celery,現(xiàn)在celery有了,要怎么來管理定時任務(wù)呢?這個時候就要用到django-celery-beat了,它的使用比較簡單。
1. 配置django-celery-beat
- 安裝
pip install django-celery-beat
- 注冊
在django的settings.py中進(jìn)行注冊
同樣,注冊之后要遷移數(shù)據(jù)庫,INSTALLED_APPS = ( ..., 'django_celery_beat', )
python manage.py migrate django-celery-beat
- 啟動
注意這個命令要在第一層proj目錄下運行,不然會報錯,提示找不到配置文件之類的錯誤celery -A proj beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler
想要單獨說明的是,很多人在使用django_celery_beat做定時任務(wù)管理的時候,喜歡把定時任務(wù)以cronjob的形式封裝在代碼中,但是我比較喜歡通過Django Admin頁面在數(shù)據(jù)庫中進(jìn)行配置。
因為封裝在代碼中,以后如果想要修改定時任務(wù),就需要重新寫代碼然后部署到環(huán)境中,不太友好,而且對于非技術(shù)人員來說,想要自己配置定時任務(wù)的可能性幾乎為零。
2. 通過Django Admin設(shè)置具體的定時任務(wù)
這一部分內(nèi)容比較簡單,把Django啟動,登錄到Admin頁面之后通過頁面點擊創(chuàng)建即可,不難,但是想寫出來要接很多圖,就不是很想寫了。文章來源:http://www.zghlxwxcb.cn/news/detail-726726.html
四、參考
- First Steps with Django
- Task result backend settings
歡迎關(guān)注我的公眾號
文章來源地址http://www.zghlxwxcb.cn/news/detail-726726.html
到了這里,關(guān)于利用Django和Celery管理定時任務(wù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!