{"id":35722,"date":"2019-10-31T22:05:58","date_gmt":"2019-10-31T19:05:58","guid":{"rendered":"https:\/\/prohoster.info\/blog\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh\/"},"modified":"2019-10-31T22:05:58","modified_gmt":"2019-10-31T19:05:58","slug":"roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh","title":{"rendered":"RoadRunner : PHP n'est pas fait pour mourir, ou Golang vient \u00e0 la rescousse","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"RoadRunner : PHP n&#039;est pas fait pour mourir, ou Golang vient \u00e0 la rescousse\" src=\"\/wp-content\/uploads\/2019\/06\/d2a69318cf25caa8fb49efedb333d7f8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nBonjour, Habr ! Nous travaillons activement chez Badoo <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/badoo\/blog\/430722\/\">sur la performance de PHP<\/a><\/noindex>, car nous avons un assez grand syst\u00e8me dans ce langage, et la question de la performance est une question d'\u00e9conomie d'argent. Il y a plus de dix ans, nous avons cr\u00e9\u00e9 PHP-FPM, qui \u00e9tait d'abord un ensemble de correctifs pour PHP, mais qui a ensuite \u00e9t\u00e9 int\u00e9gr\u00e9 dans la version officielle.<\/p>\n<p>Au cours des derni\u00e8res ann\u00e9es, PHP a beaucoup progress\u00e9 : le ramasse-miettes s'est am\u00e9lior\u00e9, la stabilit\u00e9 a augment\u00e9 \u2014 aujourd'hui, il est possible d'\u00e9crire des d\u00e9mons et des scripts de longue dur\u00e9e en PHP sans trop de probl\u00e8mes. Cela a permis \u00e0 Spiral Scout d'aller plus loin : RoadRunner, contrairement \u00e0 PHP-FPM, ne nettoie pas la m\u00e9moire entre les requ\u00eates, ce qui permet un gain de performance suppl\u00e9mentaire (bien que cette approche complique le processus de d\u00e9veloppement). Nous exp\u00e9rimentons actuellement avec cet outil, mais nous n'avons pas encore de r\u00e9sultats \u00e0 partager. Pour rendre l'attente plus agr\u00e9able, <b>nous publions une traduction de l'annonce de RoadRunner de Spiral Scout.<\/b><\/p>\n<p>L'approche de l'article nous est famili\u00e8re : dans nos t\u00e2ches, nous utilisons \u00e9galement le duo PHP et Go, tirant parti des avantages des deux langages sans renoncer \u00e0 l'un au profit de l'autre.<\/p>\n<p>Profitez-en !<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Au cours des dix derni\u00e8res ann\u00e9es, nous avons cr\u00e9\u00e9 des applications pour des entreprises de la liste <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Fortune_Global_500\">Fortune 500<\/a><\/noindex>, ainsi que pour des entreprises ayant une audience de moins de 500 utilisateurs. Pendant tout ce temps, nos ing\u00e9nieurs ont principalement d\u00e9velopp\u00e9 le backend en PHP. Mais il y a deux ans, quelque chose a eu un fort impact non seulement sur la performance de nos produits, mais aussi sur leur \u00e9volutivit\u00e9 \u2014 nous avons int\u00e9gr\u00e9 Golang (Go) dans notre pile technologique.<\/p>\n<p>Nous avons imm\u00e9diatement d\u00e9couvert que Go nous permet de cr\u00e9er des applications plus grandes avec des augmentations de performance allant jusqu'\u00e0 40 fois. Gr\u00e2ce \u00e0 lui, nous avons pu \u00e9tendre des produits existants, \u00e9crits en PHP, en les am\u00e9liorant gr\u00e2ce \u00e0 la combinaison des avantages des deux langages.<\/p>\n<p>Nous allons vous expliquer comment la combinaison Go et PHP aide \u00e0 r\u00e9soudre des t\u00e2ches de d\u00e9veloppement r\u00e9elles et comment elle est devenue, pour nous, un outil capable de r\u00e9soudre certains des probl\u00e8mes li\u00e9s \u00e0 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/post\/179399\/\">le mod\u00e8le de \u00ab d\u00e9clin \u00bb de PHP<\/a><\/noindex>.<\/p>\n<h3>Votre environnement quotidien de d\u00e9veloppement PHP<\/h3>\n<p>\nAvant de parler de la fa\u00e7on dont Go peut revitaliser le mod\u00e8le de \u00ab d\u00e9clin \u00bb de PHP, examinons votre environnement standard de d\u00e9veloppement PHP.<\/p>\n<p>Dans la plupart des cas, vous lancez l'application \u00e0 l'aide d'une combinaison de serveur web nginx et de serveur PHP-FPM. Le premier sert des fichiers statiques et redirige les requ\u00eates sp\u00e9cifiques vers PHP-FPM, qui ex\u00e9cute le code PHP. Il est possible que vous utilisiez une combinaison moins populaire d'Apache et de mod_php. Mais bien qu'elle fonctionne un peu diff\u00e9remment, les principes restent les m\u00eames.<\/p>\n<p>Examinons comment PHP-FPM ex\u00e9cute le code de l'application. Lorsque la requ\u00eate arrive, PHP-FPM initialise un processus PHP enfant et transmet les d\u00e9tails de la requ\u00eate comme partie de son \u00e9tat (_GET, _POST, _SERVER, etc.). <\/p>\n<p>L'\u00e9tat ne peut pas changer pendant l'ex\u00e9cution du script PHP, c'est pourquoi il n'y a qu'une seule fa\u00e7on d'obtenir un nouvel ensemble de donn\u00e9es d'entr\u00e9e : en nettoyant la m\u00e9moire du processus et en l'initialisant \u00e0 nouveau.<\/p>\n<p>Ce mod\u00e8le d'ex\u00e9cution pr\u00e9sente de nombreux avantages. Vous n'avez pas \u00e0 vous soucier de la consommation de m\u00e9moire, tous les processus sont compl\u00e8tement isol\u00e9s, et si l'un d'eux \"meurt\", il sera automatiquement recr\u00e9\u00e9, ce qui n'affectera pas les autres processus. Mais cette approche a \u00e9galement des inconv\u00e9nients, qui se manifestent lors de la tentative de mise \u00e0 l'\u00e9chelle de l'application.<\/p>\n<h3>Inconv\u00e9nients et inefficacit\u00e9 de l'environnement PHP classique<\/h3>\n<p>\nSi vous \u00eates un d\u00e9veloppeur PHP professionnel, vous savez par o\u00f9 commencer un nouveau projet : par le choix d'un framework. Il repr\u00e9sente des biblioth\u00e8ques pour l'injection de d\u00e9pendances, des ORM, des traductions et des mod\u00e8les. Et, bien s\u00fbr, toutes les donn\u00e9es d'entr\u00e9e des utilisateurs peuvent \u00eatre facilement regroup\u00e9es en un seul objet (Symfony\/HttpFoundation ou PSR-7). Les frameworks, c'est g\u00e9nial !<\/p>\n<p>Mais tout a un prix. Dans tout framework de niveau entreprise, pour traiter une simple requ\u00eate utilisateur ou une interaction avec la base de donn\u00e9es, vous devrez charger au moins des dizaines de fichiers, cr\u00e9er de nombreuses classes et analyser plusieurs configurations. Mais le pire, c'est qu'apr\u00e8s chaque t\u00e2che, vous devrez tout r\u00e9initialiser et recommencer : tout le code que vous avez r\u00e9cemment initialis\u00e9 devient inutile, et vous ne pourrez pas traiter une autre requ\u00eate avec. Dites cela \u00e0 n'importe quel programmeur qui \u00e9crit dans un autre langage, et vous verrez de la perplexit\u00e9 sur son visage.<\/p>\n<p>Les ing\u00e9nieurs PHP cherchaient depuis des ann\u00e9es des moyens de r\u00e9soudre ce probl\u00e8me, utilisant des m\u00e9thodologies r\u00e9fl\u00e9chies de \u00ab chargement paresseux \u00bb, des micro-frameworks, des biblioth\u00e8ques optimis\u00e9es, du cache, etc. Mais au final, ils doivent toujours tout red\u00e9marrer et recommencer encore et encore.<i> (Note du traducteur : une partie de ce probl\u00e8me sera r\u00e9solue avec l'apparition de <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.php.net\/rfc\/preload\">preload<\/a><\/noindex> dans PHP 7.4)<\/p>\n<h3>PHP peut-il survivre \u00e0 plus d'une requ\u00eate avec Go ?<\/h3>\n<p>\n<\/i>Il est possible d'\u00e9crire des scripts PHP qui vivent plus de quelques minutes (jusqu'\u00e0 des heures ou des jours) : par exemple, des t\u00e2ches cron, des parseurs CSV, des d\u00e9composeurs de files d'attente. Tous fonctionnent selon un m\u00eame sc\u00e9nario : extraire une t\u00e2che, l'ex\u00e9cuter, attendre la suivante. Le code reste constamment en m\u00e9moire, \u00e9conomisant des millisecondes pr\u00e9cieuses, car le chargement du framework et de l'application n\u00e9cessite de nombreuses \u00e9tapes suppl\u00e9mentaires.<\/p>\n<p>Cependant, il n'est pas si simple de d\u00e9velopper des scripts de long terme. La moindre erreur tue compl\u00e8tement le processus, le diagnostic des fuites de m\u00e9moire est frustrant, et il n'est plus possible d'utiliser le d\u00e9bogage par F5.<\/p>\n<p>La situation s'est am\u00e9lior\u00e9e avec la sortie de PHP 7 : un ramasse-miettes fiable a \u00e9t\u00e9 introduit, le traitement des erreurs est devenu plus facile et les extensions du noyau sont d\u00e9sormais prot\u00e9g\u00e9es contre les fuites. Cependant, les ing\u00e9nieurs doivent toujours faire attention \u00e0 la m\u00e9moire et garder \u00e0 l'esprit les probl\u00e8mes d'\u00e9tat dans le code (y a-t-il une langue dans laquelle on peut ignorer ces choses ?). Mais malgr\u00e9 cela, PHP 7 r\u00e9serve moins de surprises.<\/p>\n<p>Peut-on prendre le mod\u00e8le de fonctionnement des scripts PHP de longue dur\u00e9e, l'adapter \u00e0 des t\u00e2ches plus triviales comme le traitement des requ\u00eates HTTP et ainsi \u00e9liminer la n\u00e9cessit\u00e9 de tout recharger \u00e0 chaque requ\u00eate ?<\/p>\n<p>Pour r\u00e9soudre ce probl\u00e8me, il fallait d'abord impl\u00e9menter une application serveur capable de recevoir des requ\u00eates HTTP et de les rediriger une par une vers le travailleur PHP, sans le tuer \u00e0 chaque fois.<\/p>\n<p>Nous savions que nous pouvions \u00e9crire un serveur web en pur PHP (PHP-PM) ou en utilisant une extension C (Swoole). Bien que chaque m\u00e9thode ait ses avantages, aucune des deux options ne nous convenait \u2014 nous recherchions quelque chose de plus. Nous avions besoin non seulement d'un serveur web, mais d'une solution capable de nous lib\u00e9rer des probl\u00e8mes li\u00e9s au \u00ab d\u00e9marrage lent \u00bb en PHP, tout en \u00e9tant facilement adaptable et extensible aux applications sp\u00e9cifiques. En d'autres termes, nous avions besoin d'un serveur d'applications.<\/p>\n<p>Go peut-il aider dans ce domaine ? Nous savions que oui, car ce langage compile des applications en fichiers binaires uniques ; il est multiplateforme ; utilise son propre mod\u00e8le de gestion de la concurrence tr\u00e8s \u00e9l\u00e9gant et une biblioth\u00e8que pour travailler avec HTTP ; enfin, des milliers de biblioth\u00e8ques open-source et d'int\u00e9grations seront \u00e0 notre disposition.<\/p>\n<h3>Difficult\u00e9s de l'int\u00e9gration de deux langages de programmation<\/h3>\n<p>\nTout d'abord, il fallait d\u00e9finir comment deux applications (ou plus) pourraient communiquer entre elles.<\/p>\n<p>Par exemple, en utilisant<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/deuill\/go-php\"> la magnifique biblioth\u00e8que<\/a><\/noindex> d'Alex Paleystras, il \u00e9tait possible de mettre en \u0153uvre le partage de m\u00e9moire entre les processus PHP et Go (similaire \u00e0 mod_php dans Apache). Mais cette biblioth\u00e8que pr\u00e9sente des particularit\u00e9s qui limitent son utilisation pour r\u00e9soudre notre probl\u00e8me.<\/p>\n<p>Nous avons d\u00e9cid\u00e9 d'utiliser une autre approche, plus r\u00e9pandue : \u00e9tablir l'interaction entre les processus via des sockets\/pipes. Cette m\u00e9thode a prouv\u00e9 sa robustesse au cours des derni\u00e8res d\u00e9cennies et a \u00e9t\u00e9 bien optimis\u00e9e au niveau du syst\u00e8me d'exploitation.<\/p>\n<p>Pour commencer, nous avons cr\u00e9\u00e9 un protocole binaire simple pour l'\u00e9change de donn\u00e9es entre les processus et le traitement des erreurs de transmission. Dans sa forme la plus simple, un protocole de ce type ressemble \u00e0 un <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Netstring\">netstring<\/a><\/noindex> avec<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/prefix.go\"> avec un en-t\u00eate de paquet de taille fixe<\/a><\/noindex> (dans notre cas, 17 octets), qui contient des informations sur le type de paquet, sa taille et un masque binaire pour v\u00e9rifier l'int\u00e9grit\u00e9 des donn\u00e9es.<\/p>\n<p>Du c\u00f4t\u00e9 PHP, nous avons utilis\u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/php-src\/SocketRelay.php#L247\">la fonction pack<\/a><\/noindex>, et du c\u00f4t\u00e9 Go \u2014 la biblioth\u00e8que<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/prefix.go\"> encoding\/binary<\/a><\/noindex>.<\/p>\n<p>Un protocole ne nous semblait pas suffisant \u2014 nous avons donc ajout\u00e9 la possibilit\u00e9 d'appeler<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/codec.go\"> les services Go net\/rpc directement depuis PHP<\/a><\/noindex>. Cela nous a beaucoup aid\u00e9s durant le d\u00e9veloppement, car nous pouvions facilement int\u00e9grer les biblioth\u00e8ques Go dans les applications PHP. Le r\u00e9sultat de ce travail peut \u00eatre vu, par exemple, dans un autre de nos produits open-source<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\"> Goridge<\/a><\/noindex>.<\/p>\n<h3>R\u00e9partition des t\u00e2ches entre plusieurs workers PHP<\/h3>\n<p>\nApr\u00e8s la mise en \u0153uvre du m\u00e9canisme d'interaction, nous avons commenc\u00e9 \u00e0 r\u00e9fl\u00e9chir \u00e0 la mani\u00e8re de transmettre le plus efficacement possible les t\u00e2ches aux processus PHP. Lorsque une t\u00e2che arrive, le serveur d'applications doit choisir un worker libre pour l'ex\u00e9cuter. Si un worker\/processus termine son travail avec une erreur ou \"meurt\", nous nous en s\u00e9parons et en cr\u00e9ons un nouveau \u00e0 la place. En revanche, si le worker\/processus a r\u00e9ussi son travail, nous le ramenons dans le pool de workers disponibles pour ex\u00e9cuter des t\u00e2ches.<\/p>\n<p><img decoding=\"async\" alt=\"RoadRunner : PHP n&#039;est pas fait pour mourir, ou Golang vient \u00e0 la rescousse\" src=\"\/wp-content\/uploads\/2019\/06\/fe94ef304e0327247973ddd15723285a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPour stocker le pool de workers actifs, nous avons utilis\u00e9<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\/blob\/master\/static_pool.go\"> un canal tamponn\u00e9<\/a><\/noindex>, pour \u00e9liminer du pool les workers \"morts\" de mani\u00e8re inattendue, nous avons ajout\u00e9 un m\u00e9canisme de suivi des erreurs et des \u00e9tats des workers.<\/p>\n<p>R\u00e9sultat, nous avons obtenu un serveur PHP op\u00e9rationnel, capable de traiter toutes les demandes pr\u00e9sent\u00e9es sous forme binaire.<\/p>\n<p>Pour que notre application fonctionne comme un serveur web, il a fallu choisir une norme PHP fiable pour repr\u00e9senter toutes les requ\u00eates HTTP entrantes. Dans notre cas, nous avons simplement <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\/blob\/master\/service\/http\/request.go\">converti<\/a><\/noindex> la requ\u00eate net\/http de Go en format<noindex><a rel=\"nofollow\" href=\"https:\/\/www.php-fig.org\/psr\/psr-7\/meta\/\"> PSR-7<\/a><\/noindex>, afin qu'elle soit compatible avec la plupart des frameworks PHP disponibles aujourd'hui.<\/p>\n<p>\u00c9tant donn\u00e9 que PSR-7 est consid\u00e9r\u00e9 comme immuable (certains diront que techniquement cela n'est pas le cas), les d\u00e9veloppeurs doivent \u00e9crire des applications qui ne traitent en principe pas la requ\u00eate comme une entit\u00e9 globale. Cela s'harmonise parfaitement avec le concept de processus PHP de longue dur\u00e9e. Notre impl\u00e9mentation finale, qui n'a pas encore re\u00e7u de nom, \u00e9tait la suivante :<\/p>\n<p><img decoding=\"async\" alt=\"RoadRunner : PHP n&#039;est pas fait pour mourir, ou Golang vient \u00e0 la rescousse\" src=\"\/wp-content\/uploads\/2019\/06\/e3a3a1af1925dfc60b7f8fd256d1ae11.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Voici RoadRunner \u2014<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\"> un serveur PHP d'applications hautes performances<\/a><\/noindex><\/h3>\n<p>\nNotre premi\u00e8re t\u00e2che de test a \u00e9t\u00e9 le backend API, o\u00f9 des pics de requ\u00eates survenaient de mani\u00e8re impr\u00e9visible (de mani\u00e8re beaucoup plus fr\u00e9quente que d'habitude). Bien que dans la plupart des cas les capacit\u00e9s de nginx \u00e9taient suffisantes, nous rencontrions r\u00e9guli\u00e8rement l'erreur 502, car nous ne pouvions pas ajuster le syst\u00e8me assez rapidement pour faire face \u00e0 l'augmentation pr\u00e9vue de la charge.<\/p>\n<p>Pour remplacer cette solution, au d\u00e9but de l'ann\u00e9e 2018, nous avons d\u00e9ploy\u00e9 notre premier serveur d'applications PHP\/Go. Et nous avons imm\u00e9diatement obtenu un effet incroyable ! Non seulement nous nous sommes compl\u00e8tement d\u00e9barrass\u00e9s de l'erreur 502, mais nous avons \u00e9galement pu r\u00e9duire le nombre de serveurs de deux tiers, \u00e9conomisant une tonne d'argent et de comprim\u00e9s contre les maux de t\u00eate pour les ing\u00e9nieurs et les chefs de produits.<\/p>\n<p>\u00c0 mi-parcours de l'ann\u00e9e, nous avons perfectionn\u00e9 notre solution, l'avons publi\u00e9e sur GitHub sous la licence MIT et l'avons nomm\u00e9e <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\">RoadRunner<\/a><\/noindex>, soulignant ainsi sa vitesse et son efficacit\u00e9 incroyables.<\/p>\n<h3>Comment RoadRunner peut am\u00e9liorer votre pile de d\u00e9veloppement<\/h3>\n<p>\nApplication<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\"> RoadRunner<\/a><\/noindex> nous a permis d'utiliser Middleware net\/http c\u00f4t\u00e9 Go pour effectuer la v\u00e9rification JWT avant que la requ\u00eate n'atteigne PHP, ainsi que pour g\u00e9rer les WebSockets et agr\u00e9ger globalement les \u00e9tats dans Prometheus. <\/p>\n<p>Gr\u00e2ce \u00e0 l'RPC int\u00e9gr\u00e9, il est possible d'ouvrir l'API de n'importe quelle biblioth\u00e8que Go pour PHP sans \u00e9crire d'extensions wrappers. Plus important encore, avec RoadRunner, il est possible de d\u00e9ployer de nouveaux serveurs diff\u00e9rents de HTTP. Parmi les exemples, on peut citer le lancement de gestionnaires en PHP<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\/wiki\/AWS-Lambda\"> AWS Lambda<\/a><\/noindex>, la cr\u00e9ation de parseurs de files d'attente fiables et m\u00eame l'ajout<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/php-grpc\"> gRPC<\/a><\/noindex> \u00e0 nos applications.<\/p>\n<p>Avec les communaut\u00e9s PHP et Go, nous avons augment\u00e9 la stabilit\u00e9 de la solution, dans certains tests, la performance des applications a \u00e9t\u00e9 multipli\u00e9e par 40, nous avons am\u00e9lior\u00e9 les outils de d\u00e9bogage, r\u00e9alis\u00e9 l'int\u00e9gration avec le framework Symfony et ajout\u00e9 le support HTTPS, HTTP\/2, des plugins et PSR-17.<\/p>\n<h3>Conclusion<\/h3>\n<p>\nCertains sont encore prisonniers de la vision obsol\u00e8te de PHP comme d'un langage lent et encombrant, adapt\u00e9 uniquement \u00e0 la cr\u00e9ation de plugins pour WordPress. Ces personnes pourraient m\u00eame dire que PHP a une telle limitation : lorsque l'application devient suffisamment grande, il faut choisir un langage plus \u00ab mature \u00bb et r\u00e9\u00e9crire la base de code accumul\u00e9e depuis de nombreuses ann\u00e9es.<\/p>\n<p>\u00c0 tout cela, nous voulons r\u00e9pondre : pensez-y \u00e0 nouveau. Nous croyons que seul vous imposiez certaines limites \u00e0 PHP. Vous pouvez passer toute votre vie \u00e0 passer d'un langage \u00e0 l'autre, essayant de trouver la combinaison parfaite pour vos besoins, ou vous pouvez commencer \u00e0 percevoir les langages comme des outils. Les pr\u00e9tendus d\u00e9fauts d'un langage comme PHP peuvent en r\u00e9alit\u00e9 \u00eatre la cl\u00e9 de son succ\u00e8s. Et si vous l'associez \u00e0 un autre langage comme Go, vous cr\u00e9erez des produits beaucoup plus puissants que si vous vous limitiez \u00e0 un seul langage.<\/p>\n<p>Apr\u00e8s avoir travaill\u00e9 avec l'association Go et PHP, nous pouvons affirmer que nous sommes tomb\u00e9s amoureux d'eux. Nous ne pr\u00e9voyons pas de sacrifier l'un au profit de l'autre \u2014 au contraire, nous chercherons des moyens de tirer encore plus de b\u00e9n\u00e9fices de cette double pile.<\/p>\n<p><i>Mise \u00e0 jour : nous saluons le cr\u00e9ateur de RoadRunner et co-auteur de l'article original \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/users\/lachezis\/\" class=\"user_link\">Lachezis<\/a><\/noindex><\/i><br \/>\n<br \/>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/badoo\/blog\/434272\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041c\u044b \u0432 Badoo \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043d\u0430\u0434 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e PHP, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430 \u044d\u0442\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0438 \u0432\u043e\u043f\u0440\u043e\u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u2014 \u044d\u0442\u043e \u0432\u043e\u043f\u0440\u043e\u0441 \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u0434\u0435\u043d\u0435\u0433. \u0411\u043e\u043b\u0435\u0435 \u0434\u0435\u0441\u044f\u0442\u0438 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e PHP-FPM, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u0441\u043e\u0431\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u0430\u0442\u0447\u0435\u0439 \u0434\u043b\u044f PHP, \u0430 \u043f\u043e\u0437\u0436\u0435 \u0432\u043e\u0448\u0451\u043b \u0432 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0443. \u0417\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0433\u043e\u0434\u044b PHP \u0441\u0438\u043b\u044c\u043d\u043e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":26762,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35722","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47RoadRunner: PHP \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d, \u0447\u0442\u043e\u0431\u044b \u0443\u043c\u0438\u0440\u0430\u0442\u044c, \u0438\u043b\u0438 Golang \u0441\u043f\u0435\u0448\u0438\u0442 \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:05:58+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:05:58+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47RoadRunner : PHP n'est pas fait pour mourir, ou Golang vient \u00e0 la rescousse | ProHoster","description":"Salut, Habr !","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47RoadRunner: PHP \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d, \u0447\u0442\u043e\u0431\u044b \u0443\u043c\u0438\u0440\u0430\u0442\u044c, \u0438\u043b\u0438 Golang \u0441\u043f\u0435\u0448\u0438\u0442 \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:05:58+00:00","article:modified_time":"2019-10-31T19:05:58+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35722","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 00:30:57","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:57:45","updated":"2026-01-22 00:30:57","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/35722","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=35722"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/35722\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/26762"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=35722"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=35722"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=35722"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}