


Né pour la vitesse : la combinaison de PHP et Golang - RoadRunner
Au cours de la dernière décennie, nous avons développé des applications pour les entreprises Fortune 500 et les entreprises de 500 utilisateurs ou moins. Historiquement, nos ingénieurs ont principalement utilisé PHP pour développer le backend. Mais il y a deux ans, des problèmes sont survenus et ont gravement affecté non seulement les performances de nos produits, mais également leur évolutivité. Nous avons donc introduit Golang (Go) dans notre pile technologique.
Presque simultanément, nous avons découvert que Go nous permettait non seulement de créer des applications plus volumineuses, mais également d'améliorer les performances jusqu'à 40 fois. Grâce à lui, nous sommes en mesure d'étendre les produits existants écrits en PHP et de les améliorer en combinant le meilleur des deux langages.
Nous vous expliquerons, grâce à une vaste expérience de Go et PHP, comment l'utiliser pour résoudre de vrais problèmes de développement et comment nous pouvons le transformer en un outil pour éliminer certains des problèmes associés au PHP Death Model.
Environnement de développement PHP régulier
Avant d'expliquer comment Go améliore le modèle de mort PHP, comprenons d'abord l'environnement de développement PHP conventionnel.
Habituellement, les applications fonctionnent sur nginx et PHP-FPM. nginx gère les requêtes statiques, tandis que les requêtes dynamiques sont redirigées vers PHP-FPM, qui exécute le code PHP. Peut-être que vous utilisez Apache et mod_php, mais ils ont le même principe et seulement de légères différences dans leur fonctionnement.
Découvrez comment PHP-FPM exécute le code. Lorsqu'une requête est reçue, PHP-FPM initialise le sous-processus PHP et lui transmet les détails de la requête dans le cadre de son statut (_GET, _POST, _SERVER, etc.).
Lors de l'exécution d'un script PHP, l'état ne peut pas être modifié, il n'y a donc qu'une seule façon d'obtenir un nouvel ensemble de données d'entrée : effacer la mémoire du processus et la réinitialiser.
Ce modèle performant présente de nombreux avantages. Vous n'avez pas besoin de trop vous soucier de la consommation de mémoire, tous les processus sont complètement isolés, si l'un des processus "meurt", il sera automatiquement recréé et n'affectera pas les autres processus. Cependant, cette approche présente des inconvénients lorsque vous essayez de faire évoluer votre application.
Inconvénients et inefficacités d'un environnement PHP typique
Si vous développez professionnellement en PHP, vous savez par où commencer lors de la création d'un nouveau projet : choisir un framework. Il s'agit d'une bibliothèque pour l'injection de dépendances, l'ORM, les transformations et les méthodes de modèles. Bien entendu, toutes les données saisies par l'utilisateur peuvent être facilement placées dans un seul objet (Symfony / HttpFoundation ou PSR-7). Ces cadres sont super !
Mais tout a son prix. Dans n'importe quel framework d'entreprise, pour traiter une simple requête utilisateur ou accéder à une base de données, vous devez charger au moins quelques dizaines de fichiers, créer de nombreuses classes et analyser plusieurs configurations. Mais le pire, c'est qu'une fois chaque tâche terminée, vous devez tout réinitialiser et redémarrer : tout le code que vous venez de démarrer deviendra inutile, et avec son aide, vous ne pourrez plus traiter une autre demande. Dites cela à n'importe quel programmeur écrivant dans d'autres langages - et vous verrez la confusion sur son visage.
Depuis des années, les ingénieurs PHP cherchent des moyens de résoudre ce problème, en utilisant la technologie de chargement paresseux, les micro-frames, les bibliothèques d'optimisation, la mise en cache, etc. Mais finalement, vous devrez quand même abandonner toute l'application et recommencer *(Note du traducteur : avec l'émergence du préchargement dans PHP7.4, ce problème sera partiellement résolu)
Un processus PHP peut-il gérer plusieurs requêtes ?
Vous pouvez écrire des scripts PHP qui durent plus de quelques minutes (jusqu'à quelques heures ou jours) : par exemple des tâches Cron, des analyseurs CSV, des gestionnaires de files d'attente. Toutes ces tâches suivent un modèle : ils obtiennent une tâche, la traitent, puis obtiennent la tâche suivante. Le code réside en mémoire, ce qui évite les opérations supplémentaires de chargement des frameworks et des applications, ce qui permet de gagner un temps précieux.
Mais développer des scripts de longue durée n’est pas si simple. Toute erreur tuera le processus, un débordement de mémoire provoquera un crash et F5 ne pourra pas être utilisé pour déboguer le programme.
Les choses se sont améliorées depuis PHP 7 : un garbage collector fiable est apparu, il est devenu plus facile de gérer les erreurs et les extensions du noyau peuvent éviter les fuites de mémoire. Oui, les ingénieurs doivent encore traiter avec soin la question de la mémoire et de la mémorisation de l'état dans le code (quel langage permet de ne pas prêter attention à ces choses ?) Bien sûr, en PHP 7, il n'y a pas beaucoup de surprises.
Est-il possible d'adopter un modèle de scripts PHP résidents pour des tâches plus triviales comme la gestion des requêtes HTTP, éliminant ainsi le besoin de tout télécharger à partir de zéro pour chaque requête ?
Pour résoudre ce problème, vous devez d'abord implémenter une application serveur capable de recevoir des requêtes HTTP et de les rediriger une par une vers le travailleur PHP au lieu de la tuer à chaque fois.
Nous savons que nous pouvons écrire des serveurs web en PHP pur (PHP-PM) ou avec des extensions C (Swoole). Bien que chaque approche ait ses avantages, aucune des deux options n’a fonctionné pour nous – je voulais quelque chose de plus. Nous avions besoin de plus qu'un simple serveur Web : nous voulions une solution qui nous permettrait d'éviter les problèmes liés aux « redémarrages » en PHP, tout en étant facilement adaptable et extensible pour des applications spécifiques. Autrement dit, nous avons besoin d'un serveur d'applications.
Go peut-il aider à résoudre ce problème ? Nous savons que c'est possible car le langage compile l'application en un seul binaire ; il est multiplateforme ; utilise son propre modèle de traitement parallèle (concurrence) et ses propres bibliothèques pour gérer HTTP et enfin, nous pouvons intégrer davantage de bibliothèques Open source dans notre système. programmes.
Difficultés rencontrées lors de la fusion de deux langages de programmation
Tout d'abord, il est nécessaire de déterminer comment deux ou plusieurs applications peuvent communiquer entre elles.
Par exemple, en utilisant la bibliothèque go-php d'Alex Palaestras, le partage de mémoire entre les processus PHP et Go (tels que mod_php dans Apache) peut être réalisé. Mais la fonctionnalité de cette bibliothèque limite notre utilisation pour résoudre des problèmes.
Nous avons décidé d'utiliser une autre approche plus courante : structurer l'interaction entre les processus en utilisant des sockets/pipelines. Cette approche a prouvé sa fiabilité au cours de la dernière décennie et est bien optimisée au niveau du système d'exploitation.
Tout d'abord, nous avons créé un protocole binaire simple pour échanger des données entre les processus et gérer les erreurs de transmission. Dans sa forme la plus simple, ce type de protocole ressemble à un netstring avec un en-tête de paquet de taille fixe (17 octets dans notre exemple) qui contient des informations sur le type de paquet. Sa taille et les informations de son masque binaire sont utilisées pour vérifier les données. intégrité.
Côté PHP, nous avons utilisé la fonction pack, et côté Go, nous avons utilisé la bibliothèque encoding/binary.
Un protocole est un peu obsolète pour nous et nous avons ajouté la possibilité d'appeler les services net /rpc Go directement depuis PHP. Cette fonctionnalité nous a beaucoup aidé dans les développements ultérieurs car nous avons pu facilement intégrer les bibliothèques Go dans les applications PHP. Les résultats de ce travail peuvent être vus dans un autre de nos produits open source Goridge .
Répartir les tâches entre plusieurs PHP Workers
Après la mise en œuvre du mécanisme d'interaction, nous avons commencé à réfléchir à la manière de mieux transférer les tâches vers le processus PHP. Lorsqu'une tâche arrive, le serveur d'applications doit sélectionner un travailleur inactif pour l'exécuter. Si le processus de travail se termine par une erreur ou « meurt », nous l'effaçons et en créons un nouveau. Si le processus de travail s'exécute avec succès, nous le renvoyons au pool de travailleurs où il peut être utilisé pour effectuer des tâches.
Pour stocker le pool de processus de travail actifs, nous utilisons un canal tampon Pour effacer de manière inattendue les processus de travail « morts » du pool, nous avons ajouté un mécanisme pour suivre les erreurs et l'état des processus de travail.
Enfin, nous disposons d'un serveur PHP fonctionnel capable de gérer toute requête rendue sous forme binaire.
Pour que notre application commence à fonctionner en tant que serveur Web, nous devons choisir un standard PHP fiable pour gérer toutes les requêtes HTTP entrantes. Dans notre cas, nous convertissons simplement une simple requête net /http du format Go au format PSR-7 afin qu'elle soit compatible avec la plupart des frameworks PHP disponibles aujourd'hui.
Étant donné que PSR-7 est considéré comme immuable (certains diraient techniquement non), les développeurs doivent écrire des applications qui, en principe, ne traitent pas les requêtes comme des entités globales. Ceci est entièrement cohérent avec le concept de processus résidents PHP. Notre implémentation finale (pas encore reçue de nom) ressemble à ceci :
RoadRunner - High - Performance PHP Application Server
Notre première tâche de test était un backend API sur lequel, périodiquement, des requêtes Burst imprévisibles (plus fréquentes que d'habitude). Bien que les capacités de nginx soient suffisantes dans la plupart des cas, nous rencontrons souvent des erreurs 502 en raison de l'incapacité d'équilibrer rapidement le système face aux augmentations de charge attendues.
Pour résoudre ce problème, nous avons déployé notre premier serveur d'applications PHP/Go début 2018. Et j’ai obtenu des résultats étonnants immédiatement ! Non seulement nous avons complètement éliminé les erreurs 502, mais nous avons également réduit le nombre de serveurs des deux tiers, économisant ainsi beaucoup d'argent et résolvant un casse-tête pour les ingénieurs et les chefs de produit.
Au milieu de l'année, nous avons amélioré notre solution et l'avons publiée sur GitHub sous licence MIT sous le nom RoadRunner, soulignant ainsi son incroyable rapidité et son efficacité. Comment
RoadRunner peut améliorer votre pile de développement L'utilisation de
RoadRunner nous permet d'utiliser le middleware net/http côté Go, même de faire la validation JWT avant que la requête ne passe en PHP, ainsi que de gérer WebSocket et globals dans le statut d’agrégation Prometheus.
Grâce au RPC intégré, vous pouvez ouvrir l'API de n'importe quelle bibliothèque Go en PHP sans écrire de package d'extension. De plus, avec RoadRunner, vous pouvez déployer de nouveaux serveurs différents du HTTP. Les exemples incluent l'exécution de processeurs AWS Lambda en PHP, la création de puissants sélecteurs de file d'attente et même l'ajout de gRPC à nos applications.
En utilisant à la fois PHP et Go, la solution a été progressivement améliorée, améliorant les performances des applications de 40 fois dans certains tests, améliorant les outils de débogage, mettant en œuvre l'intégration avec le framework Symfony et ajoutant la prise en charge de HTTPS, HTTP /2 et. Prise en charge du PSR-17.
Conclusion
Certaines personnes sont encore liées par le concept dépassé de PHP, pensant que PHP est un langage lent et encombrant adapté uniquement à l'écriture de plugins sous WordPress. Ces gens vont même jusqu'à dire que PHP a une limite : lorsque l'application devient suffisamment volumineuse, il faut choisir un langage plus « mature » et réécrire la base de code accumulée au fil des années.
Ma réponse à ces questions est : détrompez-vous. Nous pensons que c'est vous seul qui avez fixé certaines limites à PHP. Vous pouvez passer votre vie à passer d'une langue à une autre, en essayant de trouver celle qui répond parfaitement à vos besoins, ou vous pouvez traiter les langues comme des outils. Avec un langage comme PHP, ses supposés défauts peuvent être la véritable raison de son succès. Si vous le combinez avec un autre langage comme Go, vous créez un produit plus puissant que la simple utilisation d’un seul langage.
Après avoir utilisé Go et PHP de manière interchangeable, nous pouvons dire que nous les aimons. Nous n’allons pas sacrifier l’un pour l’autre ; nous allons plutôt trouver des moyens de tirer le meilleur parti de cette double architecture.
Adresse originale en anglais : https://sudonull.com/post/6470-RoadRunner-PHP-is-not-created-to-die-or-Golang-to-the-rescue
Adresse de traduction : https : //learnku.com/php/t/61733
Apprentissage recommandé : "Tutoriel vidéo PHP"
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

PHP 8.4 apporte plusieurs nouvelles fonctionnalités, améliorations de sécurité et de performances avec une bonne quantité de dépréciations et de suppressions de fonctionnalités. Ce guide explique comment installer PHP 8.4 ou mettre à niveau vers PHP 8.4 sur Ubuntu, Debian ou leurs dérivés. Bien qu'il soit possible de compiler PHP à partir des sources, son installation à partir d'un référentiel APT comme expliqué ci-dessous est souvent plus rapide et plus sécurisée car ces référentiels fourniront les dernières corrections de bogues et mises à jour de sécurité à l'avenir.

Visual Studio Code, également connu sous le nom de VS Code, est un éditeur de code source gratuit – ou environnement de développement intégré (IDE) – disponible pour tous les principaux systèmes d'exploitation. Avec une large collection d'extensions pour de nombreux langages de programmation, VS Code peut être c

Ce tutoriel montre comment traiter efficacement les documents XML à l'aide de PHP. XML (Language de balisage extensible) est un langage de balisage basé sur le texte polyvalent conçu à la fois pour la lisibilité humaine et l'analyse de la machine. Il est couramment utilisé pour le stockage de données et

Une chaîne est une séquence de caractères, y compris des lettres, des nombres et des symboles. Ce tutoriel apprendra à calculer le nombre de voyelles dans une chaîne donnée en PHP en utilisant différentes méthodes. Les voyelles en anglais sont a, e, i, o, u, et elles peuvent être en majuscules ou en minuscules. Qu'est-ce qu'une voyelle? Les voyelles sont des caractères alphabétiques qui représentent une prononciation spécifique. Il y a cinq voyelles en anglais, y compris les majuscules et les minuscules: a, e, i, o, u Exemple 1 Entrée: String = "TutorialSpoint" Sortie: 6 expliquer Les voyelles dans la chaîne "TutorialSpoint" sont u, o, i, a, o, i. Il y a 6 yuans au total

JWT est une norme ouverte basée sur JSON, utilisée pour transmettre en toute sécurité des informations entre les parties, principalement pour l'authentification de l'identité et l'échange d'informations. 1. JWT se compose de trois parties: en-tête, charge utile et signature. 2. Le principe de travail de JWT comprend trois étapes: la génération de JWT, la vérification de la charge utile JWT et l'analyse. 3. Lorsque vous utilisez JWT pour l'authentification en PHP, JWT peut être généré et vérifié, et les informations sur le rôle et l'autorisation des utilisateurs peuvent être incluses dans l'utilisation avancée. 4. Les erreurs courantes incluent une défaillance de vérification de signature, l'expiration des jetons et la charge utile surdimensionnée. Les compétences de débogage incluent l'utilisation des outils de débogage et de l'exploitation forestière. 5. L'optimisation des performances et les meilleures pratiques incluent l'utilisation des algorithmes de signature appropriés, la définition des périodes de validité raisonnablement,

Si vous êtes un développeur PHP expérimenté, vous aurez peut-être le sentiment d'y être déjà allé et de l'avoir déjà fait. Vous avez développé un nombre important d'applications, débogué des millions de lignes de code et peaufiné de nombreux scripts pour réaliser des opérations.

Liaison statique (statique: :) implémente la liaison statique tardive (LSB) dans PHP, permettant à des classes d'appel d'être référencées dans des contextes statiques plutôt que de définir des classes. 1) Le processus d'analyse est effectué au moment de l'exécution, 2) Recherchez la classe d'appel dans la relation de succession, 3) il peut apporter des frais généraux de performance.

Quelles sont les méthodes magiques de PHP? Les méthodes magiques de PHP incluent: 1. \ _ \ _ Construct, utilisé pour initialiser les objets; 2. \ _ \ _ Destruct, utilisé pour nettoyer les ressources; 3. \ _ \ _ Appel, gérer les appels de méthode inexistants; 4. \ _ \ _ GET, Implémentez l'accès à l'attribut dynamique; 5. \ _ \ _ SET, Implémentez les paramètres d'attribut dynamique. Ces méthodes sont automatiquement appelées dans certaines situations, améliorant la flexibilité et l'efficacité du code.
