Ah, RoadRunner. Ce nom évoque soit un coyote déterminé à écraser un volatile, soit un outil PHP qui promet de transformer votre application Symfony en une bête de course. Spoiler : dans les deux cas, ça finit souvent en crash spectaculaire. Mais passons sur les métaphores animalières et parlons technique. Est-ce que RoadRunner vaut le coup pour un simple projet web Symfony ? Ou est-ce juste un marteau-piqueur pour enfoncer un clou ?
RoadRunner, c’est quoi ce truc ?
RoadRunner est un serveur d’applications PHP écrit en Go, conçu pour remplacer le bon vieux combo nginx + php-fpm. Son argument choc ? Il garde vos workers PHP en mémoire entre les requêtes, évitant ainsi le coûteux boot de Symfony à chaque hit. Résultat : des temps de réponse qui frôlent l’instantanéité, surtout pour les APIs ou les applications lourdes en traitement.
Sur le papier, c’est séduisant. En pratique, c’est un peu comme acheter une Ferrari pour faire les courses : ça fait rêver, mais le plein d’essence et l’entretien vont vous ruiner. RoadRunner brille dans des contextes spécifiques :
- Des APIs avec un trafic élevé et des requêtes courtes (ex : microservices).
- Des jobs asynchrones gérés via des queues (avec
spiral/roadrunner-jobs). - Des applications où le
bootde Symfony est un goulot d’étranglement avéré.
Pour un simple projet web – un blog, un site vitrine, une appli CRUD basique – RoadRunner est souvent un overkill. Pourquoi ? Parce que le gain de performance sera marginal, voire imperceptible, face à la complexité ajoutée.
Le piège du « mais c’est plus rapide ! »
Oui, RoadRunner est plus rapide. Non, ça ne veut pas dire que c’est utile pour votre projet. Voici pourquoi :
1. Le boot de Symfony n’est pas toujours le problème. Si votre appli passe 500ms à faire des requêtes SQL ou à générer des PDF, gagner 50ms sur le boot ne changera rien. Profilez d’abord avec Blackfire ou XHProf avant de sauter sur RoadRunner.
2. La complexité cachée. RoadRunner n’est pas un drop-in replacement. Il faut :
- Configurer un fichier
.rr.yaml(et prier pour que la doc soit à jour). - Adapter votre code pour gérer les workers (ex : éviter les fuites mémoire).
- Mettre en place un système de cache distribué si vous scalez (Redis, Memcached).
- Gérer les logs et les métriques différemment (RoadRunner a ses propres outils).
3. Le débogage devient un cauchemar. Avec php-fpm, une requête = un processus. Avec RoadRunner, un worker peut traiter des centaines de requêtes avant de redémarrer. Résultat : les bugs intermittents deviennent des énigmes dignes de Sherlock Holmes.
4. Le ROI est nul pour un projet simple. Si votre site a 100 visiteurs/jour, le gain de performance sera invisible. En revanche, le temps passé à configurer et maintenir RoadRunner sera, lui, bien réel.
Pour illustrer, voici à quoi ressemble un fichier .rr.yaml basique (et déjà complexe) :
version: '3'
rpc:
listen: tcp://127.0.0.1:6001
server:
command: "php public/index.php"
env:
APP_ENV: prod
http:
address: 0.0.0.0:8080
pool:
num_workers: 4
max_jobs: 100
allocate_timeout: 60s
destroy_timeout: 60s
logs:
mode: production
level: error
Et encore, on ne parle même pas de la configuration pour les queues ou les websockets. Bref, c’est du boulot.
Quand RoadRunner devient (enfin) intéressant
Tout n’est pas noir. RoadRunner a des cas d’usage où il brille vraiment :
- Les APIs sous haute charge. Si vous servez des milliers de requêtes/seconde, le gain de performance justifie l’effort.
- Les jobs asynchrones. RoadRunner gère nativement les queues (avec
spiral/roadrunner-jobs), ce qui évite de dépendre desupervisordou d’un broker externe comme RabbitMQ. - Les applications « long-running ». Si vos requêtes durent plusieurs secondes (ex : traitement de fichiers), RoadRunner évite de monopoliser un worker
php-fpmpendant des lustres.
Mais pour un projet web classique ? RoadRunner est comme un costume trois-pièces pour aller à la plage : ça fait pro, mais c’est juste inconfortable.
L’alternative : optimiser Symfony sans tout casser
Avant de sauter sur RoadRunner, essayez ces optimisations simples pour Symfony :
- Cachez tout ce qui peut l’être.
HTTP Cache,OPcache, etSymfony Cache(avec Redis ou APCu) font des miracles. - Passez en
APP_ENV=prod. Oui, ça semble évident, mais vous seriez surpris du nombre de projets endeven production. - Utilisez
php-fpmavec des workers bien dimensionnés. Augmentezpm.max_childrensi votre trafic le justifie. - Évitez les requêtes SQL inutiles. Un
SELECT * FROM userssur une table de 100k lignes, c’est la mort. - Activez
preloaddans PHP 7.4+. Ça réduit le temps de boot de Symfony de manière significative.
Exemple de configuration php-fpm optimisée pour un petit projet :
[www] user = www-data listen = /run/php/php8.2-fpm.sock pm = dynamic pm.max_children = 20 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 10 pm.max_requests = 500
Avec ça, vous aurez déjà des performances très correctes, sans la complexité de RoadRunner.
Conclusion : RoadRunner, oui, mais pas pour tout
RoadRunner est un outil puissant, mais comme tout outil puissant, il faut l’utiliser à bon escient. Pour un simple projet web Symfony, c’est souvent une solution disproportionnée, qui ajoute de la complexité sans apporter de bénéfices tangibles. En revanche, pour des APIs sous haute charge, des jobs asynchrones ou des applications avec des traitements longs, RoadRunner peut être un game-changer.
Avant de vous lancer, posez-vous les bonnes questions :
- Est-ce que mon projet a vraiment besoin de ces performances ?
- Suis-je prêt à gérer la complexité supplémentaire ?
- Est-ce que je ne peux pas optimiser mon code ou mon infrastructure existante ?
Si la réponse à ces questions est « non », alors RoadRunner n’est probablement pas pour vous. Et c’est très bien comme ça. Parfois, le bon vieux nginx + php-fpm reste le meilleur choix. Après tout, une voiture de course, c’est sympa, mais pour aller chercher le pain, une Twingo fait très bien l’affaire.