Celery: Memindahkan Pekerjaan Berat ke Belakang Layar
Aturan sederhana: kalau sebuah pekerjaan butuh lebih dari dua atau tiga detik, jangan kerjakan di dalam permintaan HTTP.
Kirim email, olah gambar, buat laporan, panggil LLM — semuanya masuk kategori ini.
Kenapa penting
Permintaan HTTP yang lama menahan worker server. Kalau semua worker tertahan, situsmu berhenti melayani siapa pun. Browser juga punya batas waktu sendiri — pengguna melihat error meski pekerjaannya sebenarnya berhasil.
Menyiapkan Celery
pip install celery redis
config/celery.py:
import os
from celery import Celery
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
app = Celery("config")
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()
config/__init__.py:
from .celery import app as celery_app
__all__ = ("celery_app",)
settings.py:
CELERY_BROKER_URL = "redis://localhost:6379/0"
CELERY_RESULT_BACKEND = "redis://localhost:6379/1"
CELERY_TASK_TIME_LIMIT = 30 * 60
CELERY_TASK_ACKS_LATE = True
Tugas pertama
from celery import shared_task
@shared_task(bind=True, max_retries=3)
def kirim_laporan(self, pengguna_id):
try:
pengguna = Pengguna.objects.get(pk=pengguna_id)
berkas = susun_laporan(pengguna)
kirim_email(pengguna.email, berkas)
except Exception as exc:
raise self.retry(exc=exc, countdown=60)
Memanggilnya dari view:
def minta_laporan(request):
kirim_laporan.delay(request.user.pk)
return JsonResponse({"pesan": "Laporan sedang dibuat, kami kabari lewat email."})
View-nya membalas seketika. Pekerjaannya jalan di belakang layar.
Tiga aturan yang saya pegang
1. Kirim ID, bukan objek.
kirim_laporan.delay(pengguna.pk) # benar
kirim_laporan.delay(pengguna) # salah — objek harus diserialisasi
Objek yang diserialisasi bisa jadi basi sebelum tugasnya jalan.
2. Buat tugasnya aman diulang. Celery bisa menjalankan ulang tugas yang gagal. Kalau tugasmu mengirim email, pastikan tidak mengirim dua kali.
3. Selalu pasang batas waktu. Tanpa itu, satu tugas yang macet bisa menahan worker selamanya.
Tugas terjadwal
from celery.schedules import crontab
app.conf.beat_schedule = {
"bersihkan-sesi-harian": {
"task": "core.tasks.bersihkan_sesi",
"schedule": crontab(hour=3, minute=0),
},
}
Alternatif yang lebih ringan
Celery butuh Redis atau RabbitMQ, plus proses worker terpisah. Untuk kebutuhan sederhana, itu berlebihan.
Kalau tugasmu sedikit dan tidak kritis, django-q2 atau huey lebih ringan. Kalau cuma butuh satu hal jalan tiap malam, cron biasa memanggil manage.py sudah cukup — tidak semua hal butuh antrean.
Baca Juga
Deploy Aplikasi Python: Dari Laptop ke Server
Jalan di laptop bukan berarti jalan di server. Ini yang berubah, dan kenapa.
Menyambungkan LLM ke Aplikasi Django
Pola praktis untuk memanggil model bahasa dari Django tanpa membuat aplikasimu jadi lambat.
Komentar (0)
Belum ada komentar. Jadilah yang pertama!
Tinggalkan Komentar
Komentar akan tampil setelah disetujui.