Django - 高效的後台任務調度與異步操作
現代 Web 應用常需要執行耗時或非即時的任務,例如發送郵件、處理大型數據、或與外部 API 交互。學習如何實現後台任務調度與異步操作,可以顯著提高應用的性能和用戶體驗。
課程目標
- 瞭解後台任務調度的必要性與常見工具。
- 學會使用 Celery 設計並執行異步任務。
- 探索 Django 與 asyncio 的結合,實現高效的異步操作。
- 使用 Redis 作為任務隊列的消息代理。
課程內容
1. 後台任務調度的應用場景
- 發送郵件通知:用戶註冊或購物後的郵件回執。
- 數據處理:如圖片壓縮或分析數據。
- 定時任務:例如每天生成報表或清理過期數據。
- 與外部 API 的長時間交互:如支付請求或數據同步。
2. 使用 Celery 設計後台任務
步驟 1:安裝 Celery 和 Redis
1
pip install celery[redis]
步驟 2:配置 Celery
在 Django 專案的根目錄創建 celery.py
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
# 設置 Django 的默認設定
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
app = Celery('project')
# 從 Django 的 settings.py 中加載設定
app.config_from_object('django.conf:settings', namespace='CELERY')
# 自動發現項目中的任務模組
app.autodiscover_tasks()
在 settings.py
中添加:
1
2
3
CELERY_BROKER_URL = 'redis://localhost:6379/0' # 使用 Redis 作為消息代理
CELERY_ACCEPT_CONTENT = ['json'] # 支持的數據序列化格式
CELERY_TASK_SERIALIZER = 'json' # 使用 JSON 進行序列化
在 __init__.py
中初始化:
1
2
3
4
5
6
from __future__ import absolute_import, unicode_literals
# 為 Django 應用程序導入 Celery
from .celery import app as celery_app
__all__ = ('celery_app',)
步驟 3:定義任務
在應用目錄(如 blog
)的 tasks.py
中:
1
2
3
4
5
6
7
from celery import shared_task
@shared_task
def send_email_task(to_email):
# 假設此處進行郵件發送
print(f"Sending email to {to_email}")
return f"Email sent to {to_email}"
步驟 4:調用任務
在視圖中調用異步任務:
1
2
3
4
5
from .tasks import send_email_task
def send_email_view(request):
send_email_task.delay('user@example.com') # 使用 delay() 執行任務
return HttpResponse("Email task started!")
3. 配置定時任務
步驟 1:安裝定時器
使用 Celery 與 Django-Crontab 或 Celery-Beat 配合實現定時任務:
1
pip install django-celery-beat
步驟 2:配置 Celery-Beat
在 settings.py
中添加:
1
INSTALLED_APPS += ['django_celery_beat']
運行遷移:
1
python manage.py migrate
在管理後台中新增定時任務。
4. 使用 asyncio 實現異步操作
Django 自 3.1 起支持原生異步視圖,這對於處理高並發請求非常有用。
步驟 1:設計異步視圖
1
2
3
4
5
6
import asyncio
from django.http import JsonResponse
async def async_view(request):
await asyncio.sleep(2) # 模擬耗時操作
return JsonResponse({'message': 'This is an async response!'})
步驟 2:與異步函數結合
使用 aiohttp
調用外部 API:
1
2
3
4
5
6
7
8
9
10
import aiohttp
async def fetch_data(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json()
async def async_api_view(request):
data = await fetch_data('https://api.example.com/data')
return JsonResponse(data)
5. 監控與調試
Celery 任務監控工具
- Flower:一個用於監控和管理 Celery 任務的 Web 工具。
1
2
pip install flower
celery -A project flower
訪問:http://localhost:5555
異步調試工具
- 使用
print
或logging
來記錄異步任務執行流程。 - 在
asyncio
中調用loop.set_debug(True)
開啟調試模式。
課堂練習
- 使用 Celery 為 Blog 系統新增評論審核功能。
- 設計一個定時任務,每天清理未驗證用戶。
- 編寫一個異步視圖,實現與外部天氣 API 的交互並顯示天氣資訊。
作業
- 配置 Flower 監控工具,並測試任務執行情況。
- 修改 Blog 系統,使發送郵件功能使用 Celery 異步執行。
- 為系統新增一個每日生成報表的定時任務,並將結果保存到資料庫中。
本文章以 CC BY 4.0 授權