La Duck Conf 2024 : 5 lignes de code en serverless
Lors de la Duck Conf, nous avons assisté à une conférence intitulée : 5 lignes de code en serverless.
M. Wassel Alazhar nous propose de suivre les évolutions d’architectures et de compositions de technologies proposées par les Clouds Providers, lors d’un scénario simple : un script permettant de valider une commande de réservation de chambre d’hôtel. Le script se décompose en plusieurs étapes très simples :
- Déchiffrer le message JSON ;
- Vérifier que le plan tarifaire est toujours possible ;
- Vérifier le moyen de paiement ;
- Réserver la chambre ;
- Et envoyer la confirmation de la réservation par mail.
Les promesses des lambdas fonctions sont des économies de coût, une équipe plus productive, une résilience de la solution et une meilleure agilité business. Et, en effet, cela permet d’aller vite et rapidement en production : “On n'a pas trop de questions à se poser, jusqu'à ce qu’on en mette partout”.
Il évoque le paradoxe de Jevons : “À mesure que les améliorations technologiques augmentent l’efficacité avec laquelle une ressource est employée, la consommation totale de cette ressource peut augmenter au lieu de diminuer.”.
Le fournisseur de Cloud indique d’ajouter seulement deux lignes de code pour transformer une simple fonction, en lambda fonction. Il ne reste qu’à automatiser le déploiement. Cela implique qu’il faut décrire le déploiement de la base de données, les connexions vers les fournisseurs (pour le paiement par exemple) et autres compositions de composants.
Comme cela fonctionne bien, on ajoute de plus en plus de fonctionnalités.
Cela fonctionne… jusqu'à l’atteinte d’une limite de la technologie.
La taille de package par exemple. Toutes ces technologies ont des limites techniques qu'il vaut mieux ne pas dépasser. En effet, maintenant cela ne fonctionne plus.
On peut régler cela en payant plus. Ou bien, on peut reprendre en main le déploiement. On applique le théorème de l’informatique “We can solve any problem by introducting an extra level of indirection…except for the problem of too many levels of indirections”.
La première idée est de séparer la couche métier et la couche provider. Ainsi, on peut plus facilement créer une image, l’exécuter dans un container localement, etc. On vire la dépendance au cloud provider dans le code principale, en utilisant uniquement des projets open source, comme flask par exemple.
Maintenant, pour déployer, on doit rédiger une centaine de lignes, pour conteneuriser, créer et diffuser les images, etc. On donne l’image à un container, via une autre couche.
Comme cela fonctionne bien, on a de plus en plus de réservations. Du coup, on en a de moins allant jusqu’au bout du processus ! Les réservations prennent trop de temps, il y a des erreurs partielles, etc. Le partenaire d'envoi de mail ne suit plus, et on est souvent coincé avec lui. Cela fait fuir les utilisateurs.
Toujours dans le respect du grand principe de l’informatique, on ajoute alors une couche “Outbox pattern notifier”, pour notifier l’utilisateur en dehors du processus de réservation. Un nouveau déclencheur est ajouté à la base de données pour envoyer le mail lors d’une mise à jour. On découpe alors le script, pour y déplacer l’envoie de mail. Cette approche est sympa, mais crée une forte dépendance aux technologies du cloud provider.
Une nouvelle couche est alors fréquemment nécessaire, une couche passe-plat, pour déléguer l’envoie du mail au partenaire lors d’un commit à la base de données.
Puis, on ajoute des fonctionnalités, jusqu'à… ce qu’on y arrive plus.
Le métier du pricing est devenu trop compliqué. Alors, on ajoute encore une couche. On sépare le pricing de la réservation. Le cloud provider a également des services pour nous aider, via des technologies de event-driver consumer.
On fait un service à part pour le pricing, une nouvelle fonction cloud, permettant d’intégrer les mises à jour de prix. Il faut le déployer. Entre les deux fonctions, il faut maintenant un middleware de message, pour permettre la communication via une file de message.
Cela fonctionne toujours, ce n’est pas tellement plus cher, jusqu’au moment où les règles de pricing change : “on veut faire de la tarification évolutive temps réel”. Au fur et à mesure des réservations, on va ajuster les tarifs.
Et hop, encore une couche “process manager cloud native moderne”. Il nous faut maintenant un orchestrateur pour le workflow de réservation. On vérifie toujours le plan tarifaire, on valide les moyens de paiement, on crée la réservation et on envoie l’email, mais cela en plusieurs étapes via une transaction distribuée. On change de logique. On accepte toutes les réservations, non pour les valider, mais pour ensuite, les traiter en asynchrone. Cela déclenche le workflow qui confirme le résultat à la fin.
Les cinq lignes de codes initiales sont devenues une configuration de workflow, dont l’approche est spécifique au cloud provider.
Émerge alors une question d’organisation : qui va être le owner de cette intégration ? Une approche centralisée ? Ou on pousse l’ownership vers les équipes produits ? Vers les équipes event-streams ?
Pour M. Wassel Alazhar, finalement, la question la plus importante est la suivante : “est-ce que vous avez vraiment besoin de tout cela ?”. Il y a un fort impact sur l’organisation et sur la maîtrise des patterns d’architecture.
Pour le moment, les développeurs peuvent être satisfaits, jusqu’à ce qu’on change de cloud provider. Mais là, c’est une autre histoire…
Le takeaways qu’il propose est le suivant :
- Une pléthore de services :
- Le serverless baisse la barrière d’accès à certains types d’architectures (dont vous n’avez peut-être pas besoin) ;
- Il faut être prêt !
- Le contexte reste roi :
- Partez de votre besoin ;
- Le raisonnement avec le catalogue de services managés limite le choix des possibles et nous couple plus au cloud provider.
- Les promesses se méritent :
- Le serverless récompense le bon design :
- Repenser les responsabilités et ownerships ;
- Pouvoir changer de service.
- Le serverless récompense le Continuous Delivery ;
- Le serverless récompense le bon design :
- Simplicity is the ultimate sophistication :
- Introduire des abstractions est important pour maîtriser la complexité ;
- Enlever des abstractions est encore plus important.
Pour conclure : “Lorsque vous envisagez d’ajouter une couche, cherchez à en enlever une autre”.