Marketing lance une campagne e-mail à 50 000 contacts. L'interface répond « envoi programmé ». Trois heures plus tard : 200 mails partis. Flower est inaccessible, la file Redis emails affiche 48 000 messages en attente, et des workers d'export PDF monopolisent le pool depuis le cron matinal. Personne n'alertait sur la profondeur de file — Celery « marchait », les jobs attendaient dans le noir.
Celery découple l'asynchrone — il déplace la visibilité. Sans surveillance du broker, politique de retry et séparation des files, vous avez remplacé une requête HTTP lente par un arriéré invisible qui pourrit le métier des heures plus tard.
Architecture observable
| Composant | Rôle dans l'observabilité |
|---|---|
| Broker | Profondeur de file, taux de publication |
| Workers | Concurrence, prefetch |
| Flower | Interface tâches actives et échouées |
| Backend résultats | django-celery-results en base |
| Métriques | celery_exporter vers Prometheus |
Alertes minimum :
queue_length > 1000pendant dix minutes- Pic du taux d'échec de tâches
- Absence de heartbeat worker
Une tâche sans délai maximum occupe un worker jusqu'au redémarrage.
Configuration de tâches saines
@app.task(bind=True, max_retries=3, default_retry_delay=60,
soft_time_limit=300, time_limit=360)
def send_campaign(self, batch_id):
...
acks_late=True: acquittement après succès — requeue si le worker crash en cours de tâche.reject_on_worker_lostselon le broker.- Routage : gros jobs vers la file
heavy, e-mails versfast.
Prefetch : worker_prefetch_multiplier=1 pour les jobs longs — évite qu'un worker monopolise la file.
File morte et inspection des échecs
Après le maximum de tentatives :
- Stockez exception et arguments en base (
django-celery-results). - Notifiez l'équipe d'exploitation sur un canal dédié avec le contexte nécessaire pour relancer proprement.
- Prévoyez une interface admin pour relancer manuellement après correction.
Ne faites pas retry forever — un message empoisonné bloque un slot indéfiniment.
Broker et hébergement
Redis broker : simple, souvent sur un VPS Redis dédié ; persistence AOF si les messages ne doivent pas disparaître au reboot.
RabbitMQ : routage avancé, plus de charge opérationnelle.
Les workers Celery tournent en processus séparés de Gunicorn — souvent sur le même VPS pour un petit projet, sur une seconde machine si la charge augmente. Peu d'hébergeurs managés offrent Celery natif : vous gérez les workers sur VPS ou cloud.
Pour les tâches planifiées qui alimentent Celery, croisez avec cron fiable et Gunicorn nginx.
Le sommet : Celery sans tableau de bord, c'est un cron qui ment
Voici ce que « la tâche est passée par Celery » cache en réunion.
Critères de fin de travail pour une tâche Celery : métrique de profondeur de file, alerte et procédure documentée de remise en file — pas seulement le décorateur @shared_task.
Décider et avancer sans angle mort
Sur une journée, vous pouvez rendre Celery observable sans refondre toute l'architecture :
- Déployez Flower ou un exporteur Prometheus en production, pas seulement sur l'environnement de développement où personne ne regarde les files la nuit.
- Séparez les files par criticité et durée — e-mails transactionnels, exports lourds, maintenance nocturne — pour qu'un job long ne bloque pas un envoi urgent.
- Appliquez des délais d'exécution et un nombre maximum de tentatives à toutes les tâches existantes, y compris celles écrites il y a deux ans.
- Configurez une alerte lorsque la profondeur de file dépasse un seuil pendant dix à quinze minutes consécutives.
- Testez l'arrêt brutal d'un worker en pleine tâche et vérifiez que le message revient bien en file d'attente.
- Documentez qui relance une file bloquée, sous quel délai, et avec quelle procédure de contrôle après remise en route.
Comparez les VPS adaptés aux workers via l'annuaire et le comparateur.
Questions fréquentes
Comment savoir si des tâches Celery s'accumulent ?
Surveillez la longueur de file du broker avec les commandes adaptées (par exemple LLEN sur Redis ou l'interface de gestion RabbitMQ), le tableau de bord Flower et les métriques de tâches réservées ou actives. Configurez une alerte si la profondeur reste élevée plus de quinze minutes. Le site peut répondre 200 OK pendant que des milliers de jobs attendent sans que l'équipe métier le voie.
Que faire des tâches en échec répété ?
Mettez en place une file morte, activez task_acks_late avec un nombre maximum de tentatives et un backoff progressif, puis stockez les échecs dans une base inspectable comme django-celery-results. Ne relancez jamais indéfiniment : un message empoisonné monopolise un worker. Corrigez la cause racine avant toute relance en masse depuis l'interface d'administration.
Redis ou RabbitMQ comme broker ?
Redis convient aux PME et aux petits projets grâce à sa simplicité d'installation. RabbitMQ prend le dessus lorsque le routage est complexe, que la persistance des messages est critique ou que plusieurs consommateurs partagent des files avec des règles fines. Dans les deux cas, surveillez la mémoire du serveur broker et la persistance des messages en cas de redémarrage.
Combien de workers Celery ?
Dimensionnez des pools dédiés par type de file, par exemple -Q emails,exports, plutôt qu'un pool unique. Les exports lourds ne doivent pas partager le même pool que les e-mails transactionnels — sinon un envoi urgent peut attendre deux heures derrière un traitement PDF de dix minutes.
Celery transparent montre la file — Celery boîte noire la remplit pendant que le site répond 200 OK.