Comparateur indépendant · sans classement payant
Accueil / Blog / Symfony Messenger : choisir transport et retries avec intention
Technique

Symfony Messenger : choisir transport et retries avec intention

Symfony Messenger découple l'envoi d'un message de son traitement — mais un mauvais transport ou des retries aveugles transforment une panne API en tempête de doublons.

6 min Mis à jour 19 juil. 2026

Un e-commerce Symfony envoie la facture PDF via Messenger dès qu'une commande est payée. Le transport AMQP est configuré, les workers tournent — sauf que le service de génération PDF renvoie une erreur 503 pendant vingt minutes. Les retries automatiques relancent le même message quarante fois. Résultat : quarante e-mails au client et une file saturée qui masque les vrais incidents.

Messenger n'est pas qu'un « bus magique ». C'est un contrat entre le moment où vous dispatch un message et le moment où un handler l'exécute — avec choix de transport, politique de retry, middleware et failure transport. Chaque option change la résilience et le risque de duplication.

Transports : sync, Doctrine, Redis, AMQP

Symfony route les messages via des transports configurés dans messenger.yaml. Le routing (App\Message\* -> async) détermine où part chaque classe.

TransportCas d'usagePoint de vigilance
syncDéveloppement, handlers ultra-rapidesMasque latence et dépassements de délai en production
doctrine://defaultPetit volume, pas de RedisTable messenger_messages, verrous base
redis://Files légères, faible exploitationPersistance Redis, TTL des messages
amqp:// (RabbitMQ)Production multi-workers, DLXTopologie exchanges et files à documenter

Sur un VPS unique, Doctrine peut suffire pour des centaines de messages par heure. Dès que les handlers appellent des API externes ou durent plus de quelques secondes, un broker dédié évite de bloquer les requêtes web et simplifie le scaling horizontal des workers messenger:consume.

Choisir un transport, c'est choisir qui porte la garantie de livraison — pas seulement où stocker le JSON.

Retries, délais et erreurs transitoires versus permanentes

Le composant RetryStrategy (max_retries, delay, multiplier) relance les messages en échec. Sans distinction entre « API indisponible » et « charge utile invalide », vous amplifiez une erreur de code.

Appliquez peu de retries (trois à cinq) avec backoff exponentiel sur erreurs réseau. Lancez UnrecoverableMessageHandlingException pour les erreurs métier définitives. Fixez un timeout handler : un handler qui attend indéfiniment un tiers bloque un worker entier.

Testez en staging : coupez volontairement le service cible et observez le comportement de la file — pas seulement le journal du handler.

Failure transport et rejeu contrôlé

Après épuisement des retries, Messenger peut router vers un failure transport (failed://, file dédiée, ou table Doctrine). C'est votre zone de quarantaine.

Alertez quand le failure transport n'est pas vide. Utilisez messenger:failed:show et messenger:failed:retry pour rejeu après correctif. Définissez une politique de rétention : ne gardez pas six mois de messages morts sans analyse.

Sans failure transport, selon la configuration, des messages peuvent être supprimés ou bloquer un worker en boucle — deux façons différentes de « perdre » la visibilité.

Workers, supervision et cohérence de déploiement

Les workers messenger:consume async -vv --time-limit=3600 --memory-limit=128M doivent être supervisés comme des services de production. Après déploiement, redémarrez les workers (signal ou --stop-when-empty puis relance). Assurez la même version de code et variables d'environnement que PHP-FPM. Fixez limites mémoire et time-limit pour éviter les fuites lentes.

Sur Kubernetes, un Deployment séparé pour les consommateurs évite de scaler les pods web quand seule la file grossit. L'autoscaling sur la longueur de file (KEDA, Prometheus) scale le bon composant — pas le front HTTP.

Middleware, routing et handlers synchrones oubliés

Vérifiez que chaque message métier critique passe bien par async. Un handler lourd laissé en sync crée des dépassements de délai nginx et des erreurs 502 intermittentes difficiles à reproduire.

Le middleware DoctrinePingConnectionMiddleware et DoctrineCloseConnectionMiddleware évitent les connexions MySQL périmées sur des workers longue durée — un classique sur hébergement mutualisé ou base managée avec timeout agressif.

Le sommet : le transport ne garantit pas la sémantique métier

La question n'est donc pas « Redis ou RabbitMQ ? » en premier. C'est : que se passe-t-il si ce handler s'exécute deux fois ? Tant que la réponse est floue, le transport n'est qu'un détail d'infrastructure.

Décider et avancer sans angle mort

Listez vos messages avec latence acceptable, criticité et idempotence. Choisissez transport et failure transport en conséquence. Configurez les retries avec backoff, supervisez les workers, et testez la panne du service aval en staging avant la production.

Pour dimensionner Redis, RabbitMQ ou workers sur VPS et cloud européens, consultez l'annuaire et le comparateur. Les guides complètent le cadrage infrastructure PHP. Exercice utile : simulez une exception permanente — le message doit atterrir dans le failure transport sans bloquer toute la file.

Questions fréquentes

Quelle différence entre sync et async dans Messenger ?

Le transport sync exécute le handler immédiatement dans la requête HTTP — pratique en développement, dangereux en production pour les tâches lentes. Async envoie le message vers une file consommée par des workers séparés.

Doctrine transport ou Redis/AMQP ?

Doctrine convient aux petits projets sans broker dédié, mais la table messages devient un goulot. Redis ou AMQP scale mieux dès que le volume, la latence ou le parallélisme augmentent.

À quoi sert le failure transport ?

Il isole les messages en échec après épuisement des retries, pour inspection et rejeu manuel. Sans failure transport configuré, les messages peuvent disparaître ou bloquer la consommation.

Comment éviter les doublons avec les retries ?

Rendez les handlers idempotents (verrou, statut en base) et limitez les retries sur les erreurs non transitoires. Utilisez des clés métier uniques — ne comptez pas sur une livraison exactement-une-fois par défaut.


Avant d'optimiser le broker, posez une question simple : si ce message est traité deux fois, est-ce que votre métier survit ?

Comparez les hébergeurs européens

Filtrez par conformité, localisation et usage — puis ouvrez les fiches pour vérifier le périmètre réel.

Voir l'annuaire
Blog

À lire aussi

Tous les articles →