前一篇我們提到 Celery 這個工作佇列系統,這一篇我們來介紹 django-q 這個工作佇列系統,django-q 是我在 Facebook 社團裡看到有網友問才知道這個套件的。django-q 跟 Celery 相比,他是 Django 原生的,比較輕量化,也不需要搭配額外的伺服器。
專案網址:https://django-q.readthedocs.io/en/latest/
poetry add django-q
# settings
INSTALLED_APPS = [
# other apps
'django_q',
]
# django-q
Q_CLUSTER = {
'name': 'dhango_ithome_ironman',
'workers': 1,
'recycle': 500,
'timeout': 60,
'compress': True,
'save_limit': 250,
'queue_limit': 500,
'cpu_affinity': 1,
'label': 'Django Q',
'orm': 'default',
}
# patch for Python 3.8
# https://github.com/Koed00/django-q/issues/389
from multiprocessing import set_start_method
set_start_method('fork')
設定裡的最後兩行很重要,因為 django-q 跟 Python 3.8 有點水土不服,如果不加這兩行,應用程式會無法啟動,關於這個 issue 已經有人回報給 django-q 了。
接著執行 migrate ,這會在資料庫裡建立 django-q 所需的資料表格。
poetry run python manage.py migrate
先在 foodbear 下,新增 tasks.py
# foodbear/tasks.py
def substract(x, y):
return x - y
接著開啟終端機視窗,在終端機裡執行 qcluster
poetry run python manage.py qcluster
再開啟一個終端機視窗,進入 shell
>>> from django_q.tasks import async_task, result
>>> from foodbear.tasks import substract
>>> task_id = async_task(substract, 10, 7)
>>> print(f"result={result(task_id)}")
3
async_task 與 result 是 django-q 提供的函式,將要執行的函式以及函式參數傳入 async_task 函式就可以拿到一個字串,這是 task 的 id。要取得結果,則是將前面從 async_task 所得到的 task id 傳入 result 函式就可以了。
django-q 相對於 Celery,它的基底是 Django,簡單設定,而且速度也快,不需要依賴其他服務,這是他的優勢。未來需要擴充時,也可以改為使用 Redis 等 Broker backend ,所以,可以視情境來選擇適當的工作佇列系統來使用。
範例程式碼位置:https://github.com/elleryq/ithome-iron-2020-django/tree/day-25