Nov 14
Serverless

SERVERLESS & PHP : MAIS OÙ EST PASSÉ LE SERVEUR ?

Traditionnellement, l’hébergement a toujours été orienté « ressource » : on paye un serveur, on loue un espace disque que l’on va gérer pour faire tourner nos applications et nos fichiers, avec toutefois certaines limites comme pour les montées en charge.

Matthieu Napoli, consultant technique indépendant, nous familiarise avec Serverless  :

 

L’APPROCHE SERVERLESS

Avec Serverless, on passe de cette notion de ressource à une approche qui est plus tournée vers le service. Concrètement, en tant que développeur, nous nous limitons au choix d’un service sans avoir à nous soucier de scalabilité, de ressources, de configurations ou de parallélisations.

  • Minimiser l’effort opérationnel

Grâce à Serverless, l’effort est considérablement réduit. En effet dans la mesure où l’on utilise un service et non plus une ressource, une grande partie de la responsabilité d’exécuter ce service est géré par le provider, c’est-à-dire Amazon, Microsoft, etc.
Par exemple, avec Amazon S3, l’effort opérationnel pour stocker les fichiers est réduit puisqu’il « suffit de les envoyer ». A contrario, gérer un espace disque implique de gérer le monitoring, la redondance, l’espace de stockage …

  • Améliorer la scalabilité

En s’appuyant sur des géants comme Amazon, la responsabilité du scaling est déportée sur le fournisseur de service et non plus sur le développeur qui se contente d’envoyer ses fichiers pour les stocker.
En effet, avec Serverless il n’y a pas de limite de stockage. Il est donc possible d’envoyer une très grande quantité de fichiers, sans risquer de faire « ramer » le géant du web.

  • Réduire les coûts

Contrairement à une ressource – payée qu’elle soit utilisée ou non – l’approche Serverless peut potentiellement vous aider à réduire votre facture. Avec l’approche Serverless, et notamment avec Amazon S3, vous ne payez que ce que vous consommez.
Pour certaines applications, vous n’allez pas y gagner beaucoup car vous exploiterez déjà parfaitement vos ressources, tandis que dans une bonne majorité des cas, il est possible d’économiser beaucoup à ne plus payer des ressources gâchées.

FUNCTION AS SERVICE

Avec PHP, nous avons déjà l’habitude d’avoir un process qui s’exécute quand une requête arrive avec PHP-FPM, ce qui match très bien avec l’esprit Serverless !  Paradoxalement, malgré deux architectures très proches, PHP est mal supporté dans les providers pour « Function as a service ».

Avec le service « exécuter du code » ou « FAS », l’approche Serverless est encore plus claire : Vous souhaitez exécuter une fonction ? C’est le provider qui va s’en occuper.

C’est-à-dire que vous avez dans votre application web, avec une requête http qui arrive et qui la déclenche :

Avec une approche dite traditionnelle, vous aviez un serveur qui tourne tout le temps, qui écoute et qui attend les requêtes sur le port 80, puis qu’il exécute lorsqu’elles arrivent :

 

Sur des applis de type traditionnelles comme Java, Node, Python, Go… il y a un gros refactoring, il faut enlever le serveur et on ne va écrire plus que nos Controller et le code qui va autour, ce qui demande un petit effort.

En résumé, ce changement signifie que nos applications :

  • Sont désormais exécutées par des évènements (une requête http, un job dans une message Q, un cron …) et ne vont plus tourner en tâches de fond de manière continue
  • Sont stateless, c’est-à-dire que chaque bout de code qui s’exécute pour gérer une requête va être complètement isolé des autres, il n’y aura plus d’interactions, plus de mémoire partagée, etc.

Toutefois cette situation n’est pas bloquante.
Par exemple ici on a créé dans Amazon une lambda, c’est-à-dire une fonction :

  • On télécharge le code en zip
  • On choisit son langage (attention php n’existe pas sur Amazon)
  • On choisit son Handler
  • Puis on configure l’évènement qui va déclencher votre lambda

 

 

 

Ex de code à zipper : 

CÔTÉ SCALABITÉ

En reprenant le schéma initial, si on a une requête alors le code s’exécute, si on a O requête le code ne s’exécute pas.

Mais que ce passe-t-il quand on a 1000 requêtes, au même moment, à la même milliseconde ?

 

Le code va être instancié 1000 fois, chaque code instancié va traiter 1 requête et ensuite va s’éteindre.
C’est stateless, c’est-à-dire que rien n’est partagé entre toutes ces instances : la seule limite théorique est la puissance de calcul d’Amazon.

CÔTÉ COÛT

Sur ce Graph du trafic en production, on observe des pics et des creux.
En prenant une approche orientée ressources, on va choisir des serveurs qui sont capables de gérer ces pics, dimensionnés par rapport à cette problématique.
On paie donc quelque chose qui va couvrir ce pic :

En approche Serverless vous ne payez que le « bleu » et non plus la « grosse boite ».
Plus on a de rose, plus on paie pour de la ressource inutilisée et plus on perd de l’argent, et plus on est gagnant à passer sur un hébergement Serverless.

Aujourd’hui il y existe des approches auto scaling, mais elles restent compliquées à mettre en place. Avec l’approche Serverless, notre programme s’écrit on ne paie donc que l’exécution de notre programme.


Exemple de provider pour « fonction as a service » :

  • Amazon AWS Lambda, populaire, stable et robuste
  • IBM OpenWhisk, qui est un conteneur docker et qui permet d’utiliser PHP
  • Microsoft Azure, qui supporte PHP mais qui est peu documenté
  • Google Cloud Function

 

SI PHP N’EST PAS SUPPORTÉ PAR AMAZON LAMBA, COMMENT FAIRE ?

Une lambda est un conteneur, un conteneur, est une machine linux : PHP peut être compilé pour linux, qu’Amazon utilise dans ses lambda !

Alors Comment faire ?

En créant une lambda, puis en mettant le binaire PHP dedans ; on fait une lambda en Node, en Go ou en Python avec trois lignes de JavaScript et ce handler va exécuter PHP.
Ce bridge permet ainsi de pallier à l’absence de PHP sur Amazon lambda.
Cette solution est stable et fonctionne très bien car il n’est pas nécessaire de recoder un reverse proxy, un Varnish ou autre … : un lambda traite une requête ce qui rend la possibilité et la mise en place d’un bridge très simplement !
Vous trouverez beaucoup de scripts existants sur GitHub, mais la compilation peut être vite laborieuse : avec Bref (github.com/mnapoli/bref), une librairie d’abstraction de la technologie Serverless pour PHP, vous pourrez exécuter un binaire PHP via un handler JavaScript.

LES PERFORMANCES

Comparons deux lambda, Node et PHP :

En prenant la plus petite, les performances ne sont pas idéales, en effet si on a une application qui prend 100 ms, avec Node elle va faire 108ms et 420ms avec PHP.
On observe qu’en augmentant la puissance, ça se stabilise. Sur Node à partir de 1024M il n’y a plus d’overhead à l’exécution et on se stabilise entre 20 et 21ms.

Pour 80% des application PHP, 20ms reste acceptable : on gagne en effet une scalabilité phénoménale et un temps de réponse stable, d’autant plus en cas de pics de trafic. N’oubliez pas qu’il n’y a pas de file d’attente, tout est traité en même temps !

CE À QUOI VOUS ATTENDRE

  • Base de données: si vous avez l’habitude d’avoir une stack LAMP avec un serveur où vous avez PHP et MySQL, il n’y a plus MySQL dans les conteneurs ! Il faut penser à prendre une base de données séparée comme Amazon Aurora Serverless (MySQL et PostgreSQL « as a service ») : ils vont s’occuper de faire du scaling à une granularité très faible sur la base de données.
  • FileSystem:  le système de fichier est ReadOnly. En effet, pour que la lambda soit stateless, on ne peut rien écrire sur le disque. Il existe quand même un dossier temporaire si nécessaire.
  • Logs et sessions: Les stocker sur les disques n’est pas recommandé en terme de performances. Pour les logs, il existe Amazon CloudWatch, qui permet d’avoir une visibilité totale sur les ressources et applications. Quant aux sessions, ElasticCache ou DynamoDB sont de bons outils pour les gérer.
  • APCu ne fonctionne pas non plus puisqu’il s’agit d’un cache en mémoire partagée entre les process partagés, il y a Memcache, Reddis… Selonles applications cela peut demander un changement d’approche un peu plus radical.
  • Asset: si on déploie une API web http, cela ne présente aucun problème. En revanche, si vous déployez un site web avec du PHP mais aussi du JavaScript, du css … on ne peut pas passer par une lambda pour exécuter du code qui va servir à faire des fichiers statiques, il faut pousser les fichiers sur S3.

 

Retrouvez tous les articles de Matthieu sur son blog