Monitorer son débit internet
Voyons ensemble comment monitorer son débit internet avec un Raspberry Pi
Le "12 Factor app" est un manifeste qui propose 12 bonnes pratiques concernant le développement d'applications web. Ce manifeste, écrit par Adam Wiggins (co-fondateur d'Heroku), est né de ses observations et de son expérience dans le développement et le déploiement d'applications web.
Ce manifeste s'applique à tous les langages et toutes les plateformes, c'est pourquoi il se contente de décrire les décisions de conception de haut niveau sans donner de détail sur l'implémentation.
Dans ce post, nous allons parcourir ensemble ces 12 facteurs, en extraire le concept et tenter de l'appliquer au monde PHP.
Une base de code suivie avec un système de contrôle de version, plusieurs déploiements
Ce premier facteur nous dit que tout le code doit se trouver à un seul emplacement centralisé et versionné. On y apprend également qu'une base de code est à l'origine de plusieurs déploiements, et qu'un déploiement ne doit pas être lié à plusieurs bases de code. Dans le cas où du code serait commun à plusieurs applications, alors celui-ci doit être factorisé puis extrait sous forme de librairie.
En utilisant cette approche, nous avons une base de code qui ne contient que le code de l'application, et l'utilisation d'un gestionnaire de dépendances permet de récupérer les bibliothèques supplémentaires nécessaires au fonctionnement de l'application.
La solution évidente pour mettre en oeuvre ce facteur, est l'utilisation d'un système de contrôle de version (VCS) pour gérer les modifications apportées au référentiel central.
Déclarez explicitement et isolez les dépendances
Les applications web modernes sont rarement conçues comme des monolithes à usage unique. Elles sont au contraire conçues pour tirer partie de librairies (généralement externes).
Cependant l'utilisation de ces librairies externes peut introduire des problèmes :
Nous pouvons résoudre ces problèmes en utilisant un outil de gestion de dépendances. Les gestionnaires de dépendances visent à rendre la composition d'application beaucoup plus simple en récupérant et gérant les librairies pour nous. Il suffit de lister les dépendances ainsi que les versions que requiert notre application et l'outil de gestion fait le reste pour nous.
Dans le monde PHP, le gestionnaire de dépendances le plus utilisé est composer, fortement
inspiré de npm pour node et bundler pour ruby, il installe les
dépendances requise dans un dossier vendor.
Il crée également dans ce dossier vendor des fichiers d'autoload permettant de faire un mapping dépendance-namespace et
ainsi les rendre disponibles dans l'application.
La définition de ces dépendances se fait dans le fichier composer.json
et les versions réellement installées des
librairies sont trackées dans le composer.lock
afin d'installer exactement les mêmes versions sur tous les
déploiements.
Stockez la configuration dans l’environnement
Les applications web nécessitent de la configuration. Que ce soit pour spécifier l'emplacement des ressources attachées (base de données, api, ...), le réglage des préférences de l'application ou l'environnement cible (dev, prod, ...).
Pour configurer notre application, une approche souvent utilisée est le fichier de configuration; un script simple qui définit certaines variables. Mais cette approche n'est pas idéale pour plusieurs raisons :
Une meilleure approche consiste à utiliser des variables d'environnement configurées au niveau du serveur web ou du système. Ces variables sont donc spécifiques au serveur sur lequel l'application s'exécute.
En PHP, les valeurs de ces variables d'environnement peuvent être récupérées au runtime par la fonction
getenv.
Le framework Symfony va plus loin en transformant toutes les variables d'environnements commençant par SYMFONY__
en
paramètre, utilisable dans la configuration de l'application.
Traitez les services externes comme des ressources attachées
L'application ne fait pas de distinction entre les services locaux et les services tiers. Le remplacement d'une base de données PostgreSQL locale par une autre gérée chez un tiers doit pouvoir se faire sans modifications dans le code de l'application, seul la configuration doit changer.
En conséquence, le remplacement des services externes devient trivial. Cela implique également que l'application doive interagir avec ces services externes de la même façon, que l'on soit en environnement de dev ou de prod.
Prenons l'exemple d'une application Symfony (Standard Edition) avec Doctrine, les informations de connexion à la base de données sont récupérées depuis la configuration de l'application. Le switch d'une base de données locale à une base de données distante se fait par simple changement des informations de connexion à celle-ci et le code permettant cette communication n'a pas besoin de subir de modifications.
Séparez strictement les étapes de build et d’exécution
Le processus de déploiement d'une application est divisé en trois étapes distinctes :
Cela peut sembler compliqué, mais l'idée clé est simple : nous devons séparer le processus de déploiement en deux phases distinctes. La première phase est de transformer la base de code en un livrable (build). La deuxième phase consiste à mettre à jour l'environnement pour que le nouveau livrable soit utilisé (release + run).
Nous faisons cela pour trois raisons :
Exécutez l’application comme un ou plusieurs processus sans état
L'application doit être conçue pour que chaque requête puisse être traitée par des processus différents, non liés et non communicants. Ce modèle de conception "sans état et sans partage" (stateless) est indispensable à la scalabilité horizontale.
Considérons le modèle client-serveur. Dans ce modèle, nous avons des serveurs qui gèrent les demandes des clients. Si nous voulons augmenter le nombre de requêtes que le système peut gérer, nous avons deux options :
La scalabilité verticale est plus simple à court terme, mais devient rapidement coûteuse et affiche des rendements décroissants en termes de performance. La scalabilité horizontale, d'autre part, est assez linéaire en termes de coût vs performance et permet d'être tolérant aux pannes.
Exportez les services via des associations de ports
Dans certains cas, les applications web sont exécutées dans un serveur web. C'est par exemple le cas des applications web PHP fonctionnant à l'intérieur d'Apache, ou des applications web Java fonctionnant à l'intérieur de Tomcat.
Les applications "12 factor" sont auto-suffisantes, et ne se basent pas sur l'injection au moment de l'exécution d'un serveur web dans l'environnement. C'est l'application web qui expose HTTP comme un service en l'associant à un port et écoute les requêtes qui arrivent sur ce port.
On peut par exemple citer les librairies de serveur web Thin
pour Ruby, Tornado
pour Python ou encore Jetty
pour
Java.
Côté PHP, on a depuis la version 5.4.0 la possibilité de lancer un serveur web depuis PHP en CLI. Cependant la documentation PHP nous met en garde concernant ce serveur web intégré.
Avertissement
Ce serveur web a été prévu pour aider dans le développement des applications. Il peut également être utile pour les tests, et pour les démonstrations d'applications qui sont exécutées dans des environnements contrôlés. Mais par contre, il n'a pas été conçu pour être un serveur web complet. Aussi, il ne devrait pas être utilisé dans un réseau public.
Vous l'aurez compris, PHP ne permet pas de satisfaire ce point en conservant un mode de fonctionnement intégré au serveur web et non l'inverse.
Grossissez à l’aide du modèle de processus
Les processus de l'application sont considérés comme des élèves modèle. Cela signifie que, pour mettre à l'échelle notre application, nous créons plus de processus afin de tenir la charge. Nous utilisons également différent types de processus pour différents types de tâches.
L'avantage considérable de la concurrence sont les performances versus le coût. La scalabilité par la parallélisation, donc horizontale, permet une croissance quasi-linéaire en termes de coûts et de demandes traitées (à condition que l'application soit conçue pour cette stratégie de croissance).
Un autre avantage évident est la tolérance aux pannes. Une défaillance de processus ne paralysera pas l'application.
Enfin, la parallélisation offre une application plus rapide et réactive. La possibilité de différer le traitement du thread principal signifie que le serveur web n'a pas besoin d'attendre que les actions de fond se terminent avant d'envoyer la réponse HTTP au client.
Maximisez la robustesse avec des démarrages rapides et des arrêts gracieux (graceful)
Les processus sont dit jetables, c'est à dire qu'ils peuvent être démarrés ou stoppés rapidement à n'importe quel instant. Cela permet d'ajouter des processus très rapidement en cas d'augmentation de la charge sur l'application et au contraire d'en supprimer quand la charge diminue.
Trois points sont particulièrement importants ici :
Gardez le développement, la validation et la production aussi proches que possible
Les applications "12 factor" sont conçues pour le déploiement continu et la conservation d'un fossé étroit entre les différents environnements.
Le déploiement continu permet de :
L'autre point à ne pas négliger concerne les outils.
Si l'environnement de production utilise PHP 5.6 et MySQL sur Linux, l'environnement de développements doit utiliser les mêmes outils. Si le développeur utilise PHP 7.1 et Sqlite sur OS X, il augmente la probabilité d'avoir des comportement non prévus en production.
Traitez les logs comme des flux d’événements
Les logs sont des flux d’événements, ordonnés dans le temps, collectés à travers les flux de sortie de tous les processus et services externes qui tournent. Les logs, dans leur forme brute, sont au format texte avec un événement par ligne, n’ont pas de début ou de fin fixe, mais se remplissent en continu tant que l’application est en marche.
Une application "12 factor" ne s’inquiète jamais du routage ou du stockage de ses flux de sortie. Elle ne devrait pas tenter d’écrire ou de gérer les fichiers de logs. À la place, chaque processus qui tourne écrit ses flux d’événements, sans tampon, vers stdout, la sortie standard.
Par déploiement, les flux de chaque processus seront capturés par leur environnement d’exécution, assemblés avec les autres flux de l’application, et routés vers une ou plusieurs destinations pour un visionnage et un archivage de longue durée. Le lieu d’archivage n’est pas visible et ne peut être configuré par l’application : ils sont complètements gérés par l’environnement d’exécution.
Lancez les processus d’administration et de maintenance comme des one-off-processes
La formation de processus est la liste des processus qui sont utilisés pour le fonctionnement normal de l’application (comme gérer les requêtes web) lorsqu’elle tourne. Les développeurs vont souvent vouloir effectuer des tâches occasionnelles d’administration ou de maintenance, comme :
Les processus ponctuels d’administration devraient être lancés dans un environnement identique à ceux des processus standards de l’application. Ils s’exécutent sur une release, en utilisant la même base de code et configuration que tout processus qui tourne pour cette release. Le code d’administration doit être livré avec le code de l’application afin d’éviter les problèmes de synchronisation.
En PHP, il est possible d'exéctuer un script ponctuel grâce à l'exécutable php suivi du chemin vers le fichier contenant
le script (par ex. php scripts/fix_bad_records.php
).
Le composant console de Symfony facilite la création et le test de tâches
d'administrations.
Auteur(s)
Arnaud Veber
Cloud Solutions Architect & Fullstack Developer depuis 10 ans.
Je travaille aujourd'hui principalement sur des architectures web serverless & event driven hébergées sur AWS.
Vous souhaitez en savoir plus sur le sujet ?
Organisons un échange !
Notre équipe d'experts répond à toutes vos questions.
Nous contacterDécouvrez nos autres contenus dans le même thème
Voyons ensemble comment monitorer son débit internet avec un Raspberry Pi
Apprenons ensemble à scaler la gestion d'une organisation Github avec Terraform
De Github Pages à Amazon Web Services, cet article est un retour d'expérience/tutorial de notre changement d'hébergement pour le blog.