veilletech.fr
26 sept. Feed du jour
#04 SYMFONY Article

Symfony 8.2 : Messenger traite enfin en parallèle

Un worker qui attend n'est plus un worker qui bloque.

Symfony 8.2 ajoute l'option --concurrency à messenger:consume : un seul worker distribue les messages à un pool de processus enfants, 7,5 fois plus vite sur des messages de 20 ms. Le transport AMQP gagne le préchargement par prefetch_count, de 13 à 18 fois plus rapide en local, et un middleware journalise durée et mémoire de chaque message.

3 min de lectureintermédiairevidéo 1:24
Partager
Sommaire5 sections
  1. Ce qui se passe
  2. Un worker, plusieurs messages à la fois
  3. AMQP : le broker pousse au lieu d'attendre
  4. Repérer les messages lents
  5. À retenir

Ce qui se passe

Symfony 8.2 accélère Messenger sur trois fronts : le traitement concurrent dans un seul worker, un transport AMQP qui se fait pousser les messages, et un middleware qui mesure chaque message.

Un worker, plusieurs messages à la fois

Un worker Messenger traite un message après l'autre. Quand un handler attend une API ou la base, le processus reste bloqué ; pour paralléliser, il fallait lancer plusieurs messenger:consume. La nouvelle option --concurrency (contribution de Nicolas Grekas, PR #63650) change la donne :

Terminal
php bin/console messenger:consume async --concurrency=8

Le worker démarre un pool de processus enfants avec amphp/parallel — ou des threads, si l'extension PHP parallel est installée — et chacun démarre l'application. Il continue de lire lui-même le transport : une seule connexion, quel que soit le nombre de messages en cours. Sur des messages de 20 ms, --concurrency=8 va 7,5 fois plus vite qu'un worker unique.

Exception : les handlers par lots. Un lot doit rester dans un même enfant, donc la concurrence ne l'accélère pas, et l'on garde plusieurs workers pour paralléliser des lots. Si un lot ne servait qu'à gagner du temps, et non parce que traiter ensemble coûte moins cher, un handler classique avec --concurrency le remplace avantageusement.

AMQP : le broker pousse au lieu d'attendre

Le transport AMQP réclamait un message à la fois, soit un aller-retour réseau par message — la manière la moins efficace de consommer, selon RabbitMQ. L'option prefetch_count enregistre un vrai consommateur sur chaque file et laisse le broker envoyer les messages d'avance : 13 à 18 fois plus rapide face à un broker local. Les consommateurs apparaissent alors dans l'interface d'administration de RabbitMQ.

Deux précautions. Régler prefetch_count au-dessus de la taille de lecture du worker, qui vaut par défaut la valeur de --concurrency. Et savoir pourquoi l'option est désactivée par défaut : le broker décide alors de l'ordre entre les files, et les messages préchargés non traités sont redistribués à l'arrêt du worker.

Les messages différés coûtent aussi moins cher. AMQP n'ayant pas de délai natif, Symfony crée une file par valeur de délai ; avec la gigue de la stratégie de réessai, on dépassait le millier de valeurs. Les délais sont désormais arrondis à deux chiffres significatifs (5 234 ms deviennent 5 300 ms) : jamais avant l'échéance demandée, au plus 10 % après. L'option delay[granularity] impose un pas fixe en millisecondes, ou désactive l'arrondi avec 1.

Repérer les messages lents

Le middleware optionnel logging (contribution de Marie Charles, PR #64621) journalise dans le canal messenger la classe, duration_ms et memory_usage de chaque message, pour tout ce qui s'exécute après lui dans la pile. Il s'active bus par bus, et nourrit directement tableaux de bord et alertes.

Source : New in Symfony 8.2: Faster Messenger Workers, Symfony, 25 septembre 2026.