Celery là một hệ thống xử lý tác vụ phân tán mạnh mẽ, thường được tích hợp vào các ứng dụng Django để xử lý các tác vụ không đồng bộ và định kỳ.
Trường hợp sử dụng
- Ứng dụng Web: Khi người dùng thực hiện một hành động đòi hỏi thời gian xử lý dài, thay vì buộc người dùng phải chờ đợi, có thể giao tác vụ này cho Celery để thực thi bất đồng bộ. Sau khi hoàn thành, kết quả sẽ được trả về cho người dùng, giúp cải thiện đáng kể thời gian phản hồi và thông lượng của ứng dụng web.
- Tác vụ Định kỳ: Trong môi trường sản xuất, việc quản lý hàng nghìn tác vụ định kỳ trên hàng nghìn máy chủ có thể trở nên phức tạp. Celery cung cấp một giải pháp hiệu quả để lên lịch và quản lý các tác vụ này trên các máy khác nhau.
- Công việc phụ trợ: Các công việc có thể được thực hiện bất đồng bộ bao gồm gửi email/tin nhắn SMS, đẩy thông báo, dọn dẹp hoặc thiết lập bộ nhớ đệm.
Đặc trưng của Celery
- Theo dõi trạng thái thực thi của tác vụ (thành công, thất bại, thời gian xử lý).
- Quản lý tác vụ (thêm, sửa, xóa) thông qua giao diện dòng lệnh hoặc giao diện quản trị.
- Tích hợp dễ dàng với cấu hình quản lý.
- Hỗ trợ đa luồng, Eventlet và Gevent cho việc thực thi đồng thời.
- Cơ chế xử lý lỗi mạnh mẽ.
- Các cơ chế tác vụ đa dạng giúp nhóm, tách rời và xây dựng chuỗi tác vụ.
- Hỗ trợ nhiều loại message broker và backend lưu trữ.
Thiết lập Celery trong Django
Trước tiên, hãy cài đặt các gói cần thiết:
pip install django
pip install django-celery
Tiếp theo, tạo một dự án Django và một ứng dụng:
django-admin startproject myproject # Tạo dự án
django-admin startapp myapp # Tạo ứng dụng
Mở tệp myproject/myproject/settings.py và thêm 'myapp' và 'djcelery' vào INSTALLED_APPS:
INSTALLED_APPS = (
# ... các ứng dụng mặc định
'myapp',
'djcelery',
)
Để cấu hình tác vụ định kỳ, thêm đoạn sau vào settings.py:
from datetime import timedelta
# Cấu hình cho Celery Beat (lập lịch tác vụ)
CELERYBEAT_SCHEDULE = {
'greet-every-minute': {
'task': 'myapp.tasks.say_hello', # Đường dẫn tới tác vụ
'schedule': timedelta(minutes=1), # Lặp lại mỗi phút
},
}
Tại thư mục gốc của dự án (cùng cấp với settings.py), tạo tệp celery.py:
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from django.conf import settings
# Đặt module cài đặt Django mặc định cho chương trình 'celery'
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
app = Celery('myproject')
# Sử dụng chuỗi ở đây có nghĩa là worker không cần serialize đối tượng cấu hình
# sang các tiến trình con.
# - namespace='CELERY' có nghĩa là tất cả các khóa cấu hình liên quan đến celery
# sẽ có tiền tố `CELERY_`.
app.config_from_object('django.conf:settings')
# Tự động khám phá các module tác vụ từ tất cả các ứng dụng Django đã đăng ký
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
@app.task(bind=True)
def debug_task(self):
print(f'Yêu cầu: {self.request!r}')
Trong tệp myproject/myproject/__init__.py, thêm dòng sau:
from __future__ import absolute_import, unicode_literals
from .celery import app as celery_app
__all__ = ['celery_app']
Trong ứng dụng của bạn (myapp), tạo tệp tasks.py:
from __future__ import absolute_import, unicode_literals
from celery import shared_task
import datetime
@shared_task
def say_hello():
now = datetime.datetime.now()
with open("output.log", "a") as f:
f.write(f"Hello from Celery at {now}\n")
print("Hello task executed!")
Chạy Celery
Sau khi hoàn tất cấu hình, bạn sẽ thấy một số tệp được tạo ra khi dự án chạy (ví dụ: celerybeat-schedule.dat).
Để chạy Celery worker:
python manage.py celery worker -l info
Để chạy Celery beat (lập lịch tác vụ):
python manage.py celery beat
Bây giờ, tác vụ say_hello sẽ được thực thi mỗi phút và ghi vào tệp output.log.