Serverless : les pour et les contre
Le serverless apporte certes de nombreux avantages pour les développeurs, mais cela ne va pas sans compromis. Une compréhension globale est nécessaire, qui pour la plupart, fait encore défaut.
Le terme "serverless" est aujourd’hui au cœur de nombreux débats. Si les questions sont multiples certaines reviennent souvent, et illustrent une confusion entre containers et serverless ainsi que leurs avantages respectifs. Les deux architectures constituent certes des approches modernes de la gestion des applications, mais chacune d'entre elles présente des avantages spécifiques.
La meilleure façon de comprendre la différence entre les containeurs et l'architecture serverless est d’observer les communautés de développeurs respectives. La plupart de la documentation portant sur les containers Docker traite des questions relatives à la gestion de l’infrastructure et de ses outils. Ces derniers permettent de gérer plus facilement le matériel ou les machines virtuelles sous-jacentes et de répartir les containers sur plusieurs serveurs ou instances AWS. La documentation pour le serverless tend à se concentrer avant tout sur la création d'applications serverless.
Fondamentalement, le serverless permet aux développeurs de se concentrer sur l'écriture de code. Avec ce terme, les serveurs semblent se retirer de l’équation. Mais en fait, il signifie que le développeur n'a pas à se soucier de la gestion des ressources d’infrastructure. Alors que des services comme Amazon Elastic Compute Cloud (EC2) exigent que vous fournissiez des ressources pour le système d'exploitation et l'application, une architecture serverless demande simplement de la quantité de ressources que nécessite une seule demande de la fonction. Par exemple, une suite de tests Web peut nécessiter 128 Mo de RAM pour un seul site Web. Même si vous déployez 10 millions de copies de cette fonction, chaque fonction individuelle n'a besoin que de 128 Mo. Elles peuvent même fonctionner simultanément. Le serverless se concentre sur ce dont chaque requête individuelle a besoin, puis s'adapte automatiquement.
Approches de développement serverless
Il existe plusieurs approches en matière de développement serverless. Les développeurs qui utilisent généralement un framework traditionnel, comme Flask, Rails ou Express, ont la possibilité de choisir un framework adapté au serverless, comme Chalice pour Python ou Serverless pour Node.js. Ils sont en effet identiques dans leur approche ; ce qui facilite la transition pour ces développeurs.
Malheureusement, cette approche de framework unique impose des limites tant en termes de taille d’application que de complexité de l'approche. Les développeurs risquent de se heurter rapidement à des problèmes lorsqu'ils tenteront de migrer cette application vers une application serverless.
Par exemple, une fonction lambda AWS se limite à environ 50 Mo. Cela comprend toutes les dépendances, car celles-ci doivent être incluses au moment du déploiement.
Quelles approches en matière de développement ?
Autre point clé : AWS CloudFormation impose une limite à la complexité des API. Le développeur devra donc les séparer s’il y a trop de points d'extrémité ou d'opérations. En outre, les pièges du monolithisme s'appliquent également : il devient plus difficile de mettre à niveau les services, de les entretenir. De plus, on dispose d’un seul point de défaillance pour l'environnement. Cependant, avec une seule fonction, les démarrages à froid sont plus faciles à gérer.
Les microservices nécessitent une approche différente dans le serverless. Le recours à un framework est certes possible, mais il faut diviser l'API en plusieurs microservices. Cela permet de partager le code entre services qui communiquent via les invocations AWS Lambda. Prenons l’exemple d’une entreprise dont le système d’envoi email marketing repose sur plusieurs microservices. Son application est hébergée à partir d'Amazon CloudFront : il utilise un service pour permettre aux utilisateurs de prendre un template, un autre service pour choisir les destinataires et un troisième service pour l'envoi de courriels. Chacun de ces services est également divisé en microservices distincts. Le service d'emailing bâtit d'abord une liste de destinataires dans une fonction. Ensuite, il transmet le modèle de courriel et la liste de destinataires à une autre fonction, qui divise cette liste de destinataires et transmet chaque destinataire, plus le courriel, à une troisième fonction pour faire l'envoi par courriel.
Les fonctions serverless sont souvent chaînées - ce qui permet d’atténuer la limite des cinq minutes pour le runtime, ainsi que la limite de taille de 50 Mo. Dans l'exemple du système d'emailing, la première fonction, qui gère la construction de la liste des destinataires, a accès à Amazon DynamoDB (le service NoSQL d’AWS) pour extraire les destinataires. Mais il n'a pas besoin d'avoir le code installé pour traiter le modèle de courriel ou envoyer les messages.
La dernière fonction, en charge de l'emailing, n'a pas besoin d'accéder à DynamoDB, mais elle a besoin de savoir comment construire le modèle à partir des données d'entrée. Surtout, aucune de ces fonctions n'a besoin d'être exposée via Amazon API Gateway. Au lieu de cela, il s'agit d'un service séparé qui prend une requête de l'utilisateur, l'authentifie et la transmet directement au service courriel par le biais d'un appel AWS Lambda.
Pour les services complexes, comme l'exemple du système d’emailing ci-dessus, les développeurs peuvent choisir d'utiliser les fonctions AWS Step Functions au lieu de connecter les fonctions Lambda à la main. Cela apporte un support plus poussé de la gestion des erreurs et peut gérer automatiquement le transfert d'état et de données entre les fonctions. Chaque fonction est encore complètement isolée, mais l'état et les transitions sont tous gérés par AWS.
Outils de débugage d'architectures serverless
Traditionnellement, les développeurs pouvaient simplement se connecter au système, exécuter l'application, et consulter les logs et les entrées pour déboguer. Dans une architecture serverless, il n'y a pas de serveur sur lequel se connecter, et l'exécution locale peut être beaucoup plus compliquée. Certains plug-ins AWS, tels que Serverless Offline et SAM Local, permettent d'exécuter la majorité des applications hors ligne. Cependant, ceux-ci ne fonctionnent pas bien si par exemple une procédure d’autorisation est effectuée à partir d’un autre référentiel ou s’il y a plusieurs fonctions qui doivent être chaînées. Dans de nombreux cas, les développeurs doivent exécuter leur propre système pour le développement et le test, puis apporter des modifications sur un compte AWS.
Il existe plusieurs outils pour identifier les problèmes au niveau de l’application et pour assurer un suivi des performances. AWS X-Ray peut tracer automatiquement les problèmes grâce à d'autres appels vers AWS. La plupart des applications nécessite quelques lignes de code pour activer cette radiographie. Il peut ensuite afficher la cartographie du réseau et signaler les problèmes (le débit provisionné sur les tables DynamoDB ou les limites de concurrence dans Lambda). Les logs provenant d'erreurs standards sont dirigés vers Amazon CloudWatch et peuvent être ingérés dans une instance Amazon Elastic Search.
Le compromis serverless
Dans l'ensemble, le serverless permet aux équipes de développement de se concentrer davantage sur le produit et ses résultats, mais il faut prévoir davantage d’outillage pour gérer la planification, les tests et le monitoring. D’où la nécessité de cartographier le projet : cela permet de décider si ou non une architecture de microservices est possible ou souhaitable. Si elle est correctement exécutée, une architecture serverless peut faire gagner du temps dans le développement de nouvelles fonctionnalités et peut évoluer à l'infini. Si en revanche, les développeurs sautent l’étape de la planification, il faut s’attendre à ce que cela soit plus difficile à gérer.