Devoxxfr – Clean architecture

Partons d’une application qui récupère des exemples sur Internet. En Android, on va faire une sale activité, et même une seule classe. Pour refactorer l’application, on commence par appliquer les principes SOLID. Et également par la rendre testable.

Au bout d’un moment, on se retrouve avec du MVC ou MVVM (selon qu’on soit sous Android ou iOS)

Keskecé

Le concept de clean architecture, c’est d’isoler la logique métier en appliquant les patterns classiques (architecture hexagonale, DDD, …​).

Principes

  • Indépendant des frameworks
  • Définir un bon découpage métier (en particulier, définir des packages selon les fonctionnalités métier, plutôt que selon les fonctionnalités techniques)
  • Testable

Avantages

D’abord, grâce à l’utilisation d’interfaces, le code change plus facilement. On implémente les fonctionnalités plus vite …​ Une fois qu’on a construit la structure initiale. Le code est également plus réutilisable, y compris les fragments de fonctionnalités métier. D’ailleurs, comme les règles métier sont isolées, il est plus facile d’en parler avec le métier. Pour le développement d’applications mobiles, ça aide également à concevoir un modèle identique pour Android et iOS, ce qui aide évidement beaucoup les développeurs. Et ça, c’est valable même si les features ne sont pas développées à la même vitesse.

Risques

Evidement, l’overengineering peut apparaître, comme toujours. Toute l’équipe doit par ailleurs être embarquée dans la démarche. Ce que les revues de code garantissent en aval du code.

Six mois plus tard …​

Le code métier aurait pu être écrit une seule fois pour les deux plateformes mobiles (par exemple avec Kotlin native). Réfléchir à la stratégie de test dès le début aurait évité des tests fastidieux à écrire. Se passer de la clean architecture leur semble maintenant difficile. Le pattern reactive a beaucoup aidé à mettre en place ce type d’architecture. Il y a globalement moins de bug, surtout sur les couches hors domaine.

Mon avis

Manifestement, Clean architecture est plus un guide de bonnes pratiques pour architectes en herbe plutôt qu’un style architectural. Ce sont des bonnes pratiques, et comme à chaque fois, les bonnes pratiques semblent naïves et simplistes dans une conférence comme Devoxx, mais c’est à mon avis autre chose sur une application réellement utilisée. Et c’est tout l’intérêt de la chose.

Publicités

Devoxxfr – Ordinateur quantique

Un ordinateur classique, c’est simple : un circuit imprimé fait d’un bon gros paquet de transistors. Avec ça on fait des portes logiques qui, à un plus haut niveau, nous amène aux langages de haut niveau comme java ou C#. Grâce à la loi de Moore, la puissance des ordinateurs a bien augmenté. Actuellement, les transistors font 14 nanomètres. Et ça pose un problème de taille : on s’approche des bords de la physique quantique et des effets tunnels. On ne pourra donc plus gagner en puissance en améliorant les transistors.

Un peu de mécanique quantique

La physique quantique vite fait c’est

  • La superposition des états quantiques
  • Le principe d’incertitude
  • La réduction d’état quantique qui arrive quand on cherche l’état d’une particule
  • La dualité onde/particule
  • L’intrication quantique qui lie l’état de deux particules

QBit

Contrairement à un bit classique, un qbit stocke à la fois 0 et 1. Donc avec plusieurs qbits, on stocke l’ensemble des valeurs possibles pour ces qbits. Du coup, pour simuler un qbit, il faut beaucoup plus de bits (2^nombre de qbits).

Les opérateurs sont par conséquent sacrément différents. Les différents types de portes quantiques vont permettre de changer les possibilités d’apparition d’un résultat. Et donc de donner les probabilités d’apparition des différents résultats.

Par ailleurs, à cause des réductions d’état, un programme quantique pourra donner plusieurs résultats différents.

Exemples d’application

Tous les problèmes de répartition et d’optimisation (choisir les gens à une table par exemple). En chimie, trouver l’organisation d’une molécule marche bien mieux avec ce type de programmes. L’algorithme de Shore permet de trouver les facteurs premiers d’un nombre en une centaine de secondes.

Où exécuter du code quantique

Actuellement, les ordinateurs quantiques sont …​ expérimentaux (isolés magnétiquement et thermiquement). Chez Microsoft, ils travaillent sur une forme de machine quantique un peu différente, pour qu’elle soit plus stable. IBM, Google et Microsoft fournissent tous des plateformes permettant d’écrire du code quantique, mais c’est assez difficile à tester.

Mon avis

J’avais déjà lu quelques articles sur le sujet, et effectivement c’est très intéressant, mais aussi plus qu’à moitié incompréhensible. Sans doute qu’il va falloir attendre un bon moment avant que ça ne soit réellement utilisable.

Devoxxfr – Software heritage foundation

Pourquoi cette fondation ?

Autour de nous, le logiciel est partout. Et il contient une partie significative de notre connaissance et de notre héritage culturel.

Roberto nous rappelle ensuite cette fameuse citation sur l’importance de la lisibilité du code : « source code is made to be read by other human beings, and only incidentally by computers ».

Par exemple, la fonction de racine carrée écrite par John Carmak dans Doom est un code source qui est précieux et doit rester accessible. Et ça nous ouvre une fenêtre sur l’esprit du développeur.

Par ailleurs, en 50 ans, on est passé d’un code de pilotage d’Apollo 11 en 60.000 lignes au code du kernel Linux qui dépasse déja le million de lignes ! Et si le logiciel est partout, le code source lui, est hébergé chez de multiples fournisseurs (Google Code, Sourceforge, Gitorious, …​). Ce qui rend sa conservation assez complexe (surtout quand les plateformes de stockage de code source ferme). Enfin, si le logiciel est partout, il n’existe pas de plateforme de recherche pour analyser globalement le code source.

Pour combatttre ça, la software heritage fundation a été créée avec comme objectif de collecter, préserver tout le code source accessible. Actuellement, il y a déja 4 milliards de fichiers sources stockés pour 83 millions de projets.

Comment ça marche ?

Pour chaque plateforme, la SHF a créé un adaptateur permettant de collecter les codes sources utilisés. Ensuite, il faut récupérer le code source proprement dit. Actuellement, le code de GitHub et de Debian est stocké. le code de Google Code et Gitorious a été sauvé (avec l’aide de l’internet archive).

Construire pour le long terme

LA SHF a le support de l’Inria, et de l’Unesco. Cette vision est partagée avec un paquet d’organisations. Et un certain nombre d’entreprises sponsorisent l’initiative.

Comment aider ?

La SHF est du code, et peut donc avoir besoin de l’aide de développeurs (forge.softwareheritage.org). Elle a évidement besoin d’argent et de communication.

Conclusion

Il faut imaginer la SHF comme une bibliothèque d’Alexandrie du code (pour tout avoir) et un CERN du code.

Mon avis

C’est sacrément chouette ! Bravo !

Devoxxfr – Architecture hexagonale

Pourquoi ? Parce qu’à priori, les présentations sur DDD et l’architecture hexagonale ne parlent pas de framework, alors que les développeurs utilisent pas mal les frameworks.

Chez Saagie, le code s’exécute sur les bonnes machines, grâce à un container manager. Et celui-ci se trompe parfois. Ce container manager est développé avec un ensemble de couches classique. Et le code qui permettait au container manager de choisir où exécuter du code était éclaté dans plusieurs ensembles de service/DAO. Youen a donc refactoré ça dans une méthode à trois ifs.

Comment éviter ça ?

Théoriquement, l’architecture hexagonale permet d’éviter ça.

Domaine

Dans le domaine, il ne faut pas de framework. Des librairies simples peuvent en revanche être utiles.

Le domaine ne doit jamais contenir de code d’infrastructure.

Ports

Les ports sont les moyens d’appeler le domaine. Les ports primaires sont des méthodes du domaine appelables depuis l’extérieur. Et les ports secondaires sont des interfaces définies dans le domaine lui permettant d’appeler des éléments extérieurs.

Adapteurs

Les adapteurs permettent au monde extérieur d’appeler les ports.

Mise en oeuvre

Ensuite, Youen se lance dans une session de live-refactoring pour mettre en place ce type d’archiecture avec une application Spring Boot. Je vous ferai le diagramme de classe plus tard, mais globalement, en deux astuces, il arrive à écrire une application dont les règles métier sont totalement indépendantes des outils techniques utilisés pour communiquer avec le monde extérieur.

Conclusion

Avec ça, Spring est dans son cas nominal, tout comme le domaine. L’architecture hexagonale est donc parfaitement respectée, en utilisant les techniques classiques du monde Java. Le domaine est donc propre, les tests faciles et le code s’adapte beaucoup plus facilement aux échelles. En revanche, les DTO sont un peu lourds, les développeurs doivent être formés et il n’y a pas forcément de starters pour les frameworks.

Mon avis

En fait, l’architecture hexagonale, ça n’a rien de nouveau ni rien de vraiment sexy. Ca consiste surtout à séparer le code réseau du code métier et du code de stockage « d’une façon ou d’une autre ». Et si la méthode choisie par Youen est présentée comme astucieuse, elle est en fait uniquement un bon découpage en classes. Autrement dit ça n’est pas bien compliqué, c’est facilement adaptable et ça me parle puissamment.

Devoxxfr – Effective Java

Là, c’est du sérieux ! Joshua Bloch, l’auteur d’Effective Java vient nous parler de la troisième version de son livre. La deuxième datait de 2008, alors inutile de dire qu’il y a eu des changements depuis.

Joshua ne va pas nous parler de tout son livre (parce qu’il n’a que 45 minutes)

Préférer les lambdas aux classes anonymes

Avant, les classes anonymes, c’était bien (et adapté aux patterns OO). Mais ça n’est plus très pratique avec la programmation fonctionnelle. Donc les lambdas, c’est mieux. Mais avec les comparateurs, c’est un peu plus pratique (puisqu’ils construisent les lambdas à la volée).

Eviter les types sauf si ils sont nécessaires

Dans les lambdas, avec l’inférence de type, oublier les types, c’est cool. Parce que l’inférence de type, c’est magique, mais ça marche. Par contre, ça repose sur les informations des types génériques. Donc utilisez les génériques, sinon les lambdas ne marchent pas.

Utiliser les lambdas dans les enums

Avant, on pouvait faire des enums avec comportement variable grâce aux classes anonymes. Maintenant, grâce aux lambdas, c’est nettement plus facile : il suffit de passer une lambda avec l’opération variable dans le constructeur de l’enum.

Attention aux lambdas

Elles n’ont ni nom, ni documentation. Donc si vous ne comprenez pas ce que fait une lambda, faites-en une méthode. Et les classes anonymes ont quelque avantages :

  • pas besoin d’interface fonctionnelle
  • une classe anonyme a un this, et pas la lambda

Préférez les références de méthodes aux lambdas

Ca rend le code d’autant plus lisible qu’il y a de nombreux paramètres à la méthode. Et dans une lambda, il faut faire attention au nom des paramètres

Parfois, les lambdas sont plus courtes à écrire

Par exemple (x → x) est plus efficace que (Function.identity()).

Attention aux types de référence de méthode

Chaque type de méthode a sa propre déclaration de référence, ce qui peut rendre les choses un peu compliquées (mais toujours plus simples que les lambdas).

Préférez les interfaces fonctionnelles standard

L’exemple est un peu long, mais globalement, l’idée, c’est que si une interface fonctionnelle existe déjà, utilisez-la plutôt que de redéclarer la vôtre. Parce que bon, Java a déjà 43 interfaces fonctionnelles ! Les plus importantes sont UnaryOperator, BinaryOperator, Predicate, Function, Supplier, Consumer. Et puis elles fournissent déjà une API, ce qui limite ce qu’un utilisateur de votre API doit apprendre. En plus, elles fournissent des méthodes par défaut intéressantes (comme Predicate qui fournit combine et negate)

Quand ne pas les utiliser ?

Evidement, quand aucune de ces interfaces ne correspond à votre besoin. Ou alors quand votre interface fonctionnelle définit un contrat clair (comme par exemple Comparator).

Donc, écrivez votre interface fonctionnelle si

  • elle sera beaucoup utilisée
  • elle a un nom clair
  • elle définit un contrat fort
  • elle pourrait bénéficier de méthodes par défaut

Mais n’oubliez pas vos responsabilités : vous définissez une interface, et ça c’est pas de la tarte.

Utilisez les streams avec justesse

Donc un stream, c’est un flux de données traité par un pipeline dans lequel on trouve

  • un générateur
  • zéro ou plus d’opérations intermédiaires
  • et enfin une terminaison

Joshua nous montre ensuite un exemple dans lequel il remplace toutes les collections par des streams. Et c’est illisible. La conclusion est évidente : utilisez les streams avec justesse pour éviter de faire de votre code un bazar sans nom. Notez par ailleurs que les streams de caractères …​ ça ne marche pas. Par ailleurs, dans certains cas, il est difficile de déterminer si les streams seront meilleurs que les itérations traditionnelles.Enfin, la parallélisation des streams donne parfois des résultats désastreux (comme dans son exemple de calcul de nombre de Mersenne où chaque valeur dépend de toutes les valeurs précédents.

Conclusion

Java est maintenant un langage multiparadigme. Choisissez avec soin les parties que vous utilisez.

Devoxxfr – DDD & Event sourcing avec la GDPR

La GDPR keskecé

La GDPR régit la manière dont les organisations travaillent avec les données des citoyens européens à partir du 25 mai 2018. C’est bientôt. Pour une entreprise qui ne respecte pas cette GDPR, l’amende est de 4% du chiffre d’affaire du groupe plafonné (peut-être) à 20 millions d’euros. Et ce sans compter les poursuites pénales et l’information des utilisateurs.

Les données des citoyens, c’est quoi ?

  • Nom
  • Adresse
  • Adresse IP
  • Les ensembles d’information permettant d’identifier un individu

Evidement, ça donne du travail …​

Et le DDD là-dedans ?

Saagie fournit une application de data governance. Cette appli, développée à l’arrache, est basé sur un paquet de CRUD qui manipulent les données en prod. Malheureusement, les problèmes liés à la GDPR ne sont pas adressables dans ce contexte.

Donc, il ne faut pas écrire du code contraint par la technique, mais plus par le domaine métier.

Et pour ça, il y a plusieurs éléments

  • Avoir un langage commun avec des termes qui sont utilisables par chacun et compris par tous.
  • Ne pas avoir un modèle unique : ça mène d’une part à des classes énormes, et d’autre part à des problèmes de compréhension
  • Les différents contextes dans lesquels s’expriment les modèles doivent être bornés

Pour obtenir ça, la méthode de design en couche avec des DAO, et de la base de donnée qui apparaît un peu partout est peu appropriée. Mettre le domaine au centre permet en revanche de rester « propre ».

Et pour ça, se baser sur les événements peut être utile, parce que la plupart des modes sont d’une façon ou d’une autre événementiels.

Et pour construire le domaine et identifier les événements, la technique de l’event storming est assez utile.

Une fois ces événements identifiés, mettre le domaine au centre revient à mettre en place une architecture hexagonale.

Event sourcing

L’event sourcing, c’est le fait de définir les événements comme source unique de vérité. Avec ça, on peut reconstruire l’état des objets.

Ca apporte en plus

  • La testabilité
  • La gestion de version des données
  • Le debug et la reproductibilité
  • Le rollback (mais pas en supprimant le dernier événement)
  • La tracabilité
  • La recomposition des projections

En revanche, ça n’est qu’un pattern local, qui apporte évidement des inconvénients (comme par exemple le fait qu’il y aura toujours plus de données).

Questions

Comment gère-t-on les données personnelles dans un event store immuable ?

Les données personnelles ne doivent pas s’y trouver, sinon c’est foutu. Ou alors, on stocke une clé de chiffrage par utilisateur (en dehors de l’event store) et toutes les données de l’utilisateur sont chiffrées dans l’event store.

Mon avis

Les deux sujet sont intéressants, mais quel était le rapport ? En fait, il est dans les questions en fin de conférence, qui ont construit le lien.

Devoxxfr – From a french monolith to a worldwide platform

Avant, Dailymotion, c’était un gros monolithe LAMP hosté sur de vraies machines, dans un seul datacenter. L’objectif, c’était d’avoir du code qui s’exécute près du client, avec des applications go/python dans des conteneurs orchestrés par Kubernetes, et des apis GraphQL.

Pour ça, Dailymotion s’est réorganisé autour de tribus, d’escouades et de chapitres (façon Spotify). Ca permet d’aligner l’architecture et l’organisation, ce qui est toujours pratique.

Revenons à l’application. Comme le front-end communique via GraphQL, la migration se fait en douceur : c’est GraphQL qui expose les anciennes API comme les nouvelles, ce qui permet d’ajouter facilement les microservices à côté de l’application historique. Ca permet la migration facile, mais aussi l’appropriation des différents composants du code.

Déploiement de GraphQL

La mise en place de GraphQL, et des fondations de l’application, vient d’une équipe de deux personnes, qui ont mis en place un K8s déployé dans 3 régions AWS. Ca marchait assez bien, mais les infrastructures étaient peu monitorées. L’équipe a ensuite fortement grossi pour atteindre 50 personnes, ce qui a permis de déployer plus de services plus rapidement. Il y a maintenant une dizaine de déploiements par jour (sur une quinzaine de services déployés par cette équipe).

Evidement, cette croissance du personnel a dû être anticipée. Il y avait donc des sessions de formation régulières, sur K8s, la conteneurisation, GraphQL, …​ Mais aussi des modifications des différents outils de RH de la boîte.

Outillage

Pour un nouveau développeur chez Dailymotion, il y a pas mal de switch entre projets (avec des dépendances différentes, dans des versions différentes, …​). Donc la machine du développeur n’a que Docker. Et pour facilement passer d’un projet à un autre, ils ont conçu la spécification de gazr, qui permet de lancer les outils de build ou de test des différentes stacks. Grâce à cet outil, les commandes sont toujours identiques.

Orchestration

Pour facilement créer et maintenir les clusters de prod, Dailymotion utilise un K8s managé chez Google Cloud Platform. Ca permet l’autoscaling. Par ailleurs, le code est déployé sur 3 régions GCP (Europe, Afrique, Asie). Par ailleurs, le code va être migré sur un cloud hybride utilisant les datacenters existant (ceux qui fournissent le CDN utilisé par Dailymotion pour les vidéos).

Continuous deployment

L’équipe qui s’occupait des releases a été remplacé par les équipes de développement elles-mêmes grâce aux Jenkinsfile. Ce sont ces équipes qui déploient jusqu’en prod (automatiquement, sauf lorsqu’une approbation humaine est nécessaire).

Evolution du déploiement

Initialement, les applications étaient déployées par des scripts bash. Ca a été remplacé par une tentative d’application déployant sur tout le cluster via les API K8s. C’était assez complexe, et certaines étapes restaient manuelles. Actuellement, les applications sont déployées par région via Helm.

Celui-ci gère les dépendances, fournit des templates pour séparer les déploiements par environnement, et permet le rollback.

Gestion de la plateforme

L’API GraphQL est supervisée grâce à Open Tracing. Evidement, il y a du monitoring, de la supervision, des logs gérés par Elastic/FluentD/Kibana, et du feature flipping.

Rôles

Avant, il y avait trois types d’ingénieurs

  • Le software engineer écrit le code (pas forcément facile à opérer)
  • Le release engineer package et déploie l’application
  • Le system engineer opère l’application, mais ne peut pas corriger celle-ci.

Ces rôles ont été remplacés par le production engineer, qui tient chacun des rôles. Ca implique des changements organisationnels (les anciens développeurs peut se retrouver d’astreinte, il faut changer leur contrat de travail).

Ca veut aussi dire que les développeurs peuvent mettre en prod. Et par exemple, Stan, lors d’une manipulation hasardeuse, à détruit tous les conteneurs faisant tourner Dailymotion dans le monde entier. Mais grâce aux outils de rollback préparés, le retour à la normale a pu avoir lieu très rapidement. Et surtout, ils ont pu apprendre de leurs erreurs et mettre en place des outils évitant ces manipulations.

Mon avis

Un bon retour d’expérience avec quelques bonnes idées. Malheureusement, j’ai eu l’impression que la présentation restait un peu trop à la surface des choses.

Devoxxfr – Litterate programming, le roman de votre programme

Le litterature programming a été inventé par Donald Knuth …​ pas n’importe qui, en fait.

A l’époque où il conçoit ce concept, il n’est pas absurde d’écrire un programme et de le faire imprimer. C’est préciséement l’objectif de la programmation lettrée.

Donc pour ça, Knuth conçoit un outil (web) qui permet d’écrire le code et sa description dans le même fichier.

Avantages et inconvénients

Ca permet d’expliciter sa pensée. La documentation est forcément présente et à jour. On s’éloigne par ailleurs de la programmation traditionnelle pour s’approcher du langage naturel. En revanche, l’outil est verbeux. Il faut également maîtriser à la fois le code et la langue le décrivant. Le refactoring est spécialement difficile. Et actuellement, faire de la programmation lettrée est à peu près impossible, aprce qu’on écrit dans l’ordre de la pensée.

Appliquer aujourd’hui

Raphaël a tenté de le faire dans du code Java, à travers des commentaires beaucoup plus verbeux. C’est possible, mais assez peu approprié

Qu’est-ce qui s’en rapproche aujourd’hui

D’abord, il y a les commentaires du code, qui vont pouvoir expliquer pourquoi le code fonctionne de cette façon. Il y a également les commentaires de commit, mais qui sont rarement explicites. La documentation traditionnelle peut aussi aider, même si elle n’est pas écrite simultanément. La javadoc documente correctement l’API, mais n’explique pas le fonctionnement du programme.

Les tests unitaires (en TDD) peuvent expliquer correctement le fonctionnement du code, à travers la documentation associée. Mais ils sont séparés du code principal, n’expliquent pas le fonctionnement. Par ailleurs, les documenter ne documentera que les cas lister. Enfin, le formalisme est loin d’être souple.

Qu’est-ce qui pourrait fonctionner ?

Des outils graphiques, avec l’inclusion d’image. Par exemple, Jupyter ressemble pas mal conceptuellement.

Questions

En coffeescript ?

A priori, il est possible d’intégrer du coffeescript dans les pages == Est-ce que ça n’est pas impossible de lier le code et sa documentation ? C’est certes compliqué, mais ça peut approcher des choses (typiquement, Asciidoc peut intégrer du code comme dans la doc Groovy).

Mon avis

Malheureusement, j’en savais autant que le speaker sur la programmation lettrée. Et pire encore, j’ai eu l’impression d’avoir une meilleure vision de la manière « moderne » d’utiliser ces idées. Cela dit, c’est un concept qui m’a toujours paru méconnu.

Docker, Kubernetes et Istio

Docker, K8s (j’abrège, hein, parce que bon) sont souvent présentés pour les microservices, mais ça marche aussi avec les applications un peu plus grosses. C’est ce que David va montrer avec le petstore version A. Goncalvez.

Dockeriser

Pou ça, David construit son image Docker avec un multi-stage build (toujours impressionant pour le dockeriste débutant comme moi). Et paf, l’application est conteneurisée.

Lancer dans un cluster K8s

Vous connaissez Kubernetes ? ? non ? bon, David a une surprise pour vous

Avec K8s, on peut prendre un cluster de machines et travailler dessus sans trop s’en soucier. Pour lancer notre application, on crée deux descripteurs yaml (ouch, j’aime aussi peu que David).
  1. Un déploiement (qui décrit l’application à déployer)
  2. Un service (qui route le port 80 vers notre application – à la traefik/https://nginx.org/[nginx]/https://getkong.org/[kong]/https://www.sozu.io/[sozu]/…​.)

Et paf, on déploie. L’explication sur le mode de fonctionnement de K8s est un peu louche (à base de boucles de contrôle qui réconcilient des états souhaités/actuels).

Organisation

La CLI de K8s permet d’avoir des informations sur l’état du cluster, et nous montre par exemple que l’application tourne dans un pod. Si ce pod est détruit, K8s en relance un nouveau, et y redéploie l’application. C’est très très cool. On peut aussi facilement déployer l’application dans plusieurs pods, pour faire de la redondance dans ce que ça a de plus vrai : arrêter ou perdre un pod n’a aucun impact sur l’autre.

Améliorer l’appllication de l’extérieur

David ajoute maintenant un proxy nginx pour gzipper le flux, ajouter une page 404 et réécrire les urls. Pour ça, il suffit d’ajouter le proxy dans le pod de l’application. Ca veut dire un déploiement et un service décrivant nginx, un dockerfile et enfin fichier de configuration pour nginx. La particularité, c’est que nginx reroute vers localhost (ce qui n’est pas le cas quand on joue classiquement avec des conteneurs). Parce que nginx et petstore seront forcément déployées sur la même machine. Enfin, en ajoutant un ingress, il est possible de créer un nom de domaine spécifique devant le nginx. C’est vachement pratique, parce que pendant ce temps-là, petstore n’a pas changé.

Istio

Istio reprend précisément ce principe en ajoutant des facades envoy (un proxy C++) devant toutes les applications. Le proxy est configurable.

Premier apport : Istio transforme tous les flux en HTTPS. C’est dingue. C’est à la fois génial et affreux : comment débugger le traffic ?

Grâce à envoy, Istio fournit de monitoring de tous les services avec les temps de réponse,

David passe à une démo où les deux versions de l’application sont déployées côte à côte avec des urls différentes. Et grâce au smart routing d’Istio, on peut faire du blue-green deployment. Alors qu’avec K8s, c’est impossible. Bon, apparement, il y a d’autres solutions (de mémoire, OpenShift le fait aussi comme l’avait montré Clément Escoffier précédement). Pour vérifier qu’on a bien du blue-green, David affiche un dashboard grafana (installé par Istio) en ouvrant un tunnel de sa machine vers le composant Grafana (assez spectaculaire). Et ça marche ! On a bien 20% d’utilisateurs en v2 et 80% en v1.

Routage

Et maintenant, il est temps de tout réécrire. David va donc séparer l’application en plusieurs services, qui utiliseront toujours les routes de l’application initiale. Pour ça, le smart routing d’Istio est pratique …​ mis à part le fait qu’il y a de plus en plus de contenu YAML. Donc on a deux composants, qui se parlent à travers le réseau. Et forcément, avec le réseau, les problèmes arrivent. Heureusement, Istio va nous aider pour survivre à ça. D’abord grâce à un graphe des services (auquel on se connecte comme Grafana grâce à un tunnel temporaire). Et là, trop bien …​ mais trop moche …​ le graphe est généré par Grafviz (mais la version plus récente utilise D3.js).

Gestion du réseau

Encore une fois, grâce au proxy envoy, on peut configurer finement chaque composant pour, par exemple, simuler des timeouts. Ou de mirrorer le trafic de prod vers une application non utilisée en prod, mais qui en recevra la charge. Ou encore d’industrialiser les circuit breakers en les plaçant au niveau d’envoy. Ou encore de gérer la sécurité sans passer par les notions classiques et pénibles de zones de sécurité réseau, mais en utilisant une gestion de la sécurité par rôle. C’est vraiment chouette parce que ça permet d’optimiser le nombre de serveurs. Ca permet également, grâce à la télémétrie, de voir quel composant appelle quel autre service. Pour ceux qui connaissent, ça ressemble vachement à Dynatrace dans l’idée.

Rate limiting

En particulier, il est possible de limiter les appels à un service pour qu’il ne soit pas noyé sous la charge. Malheureusement, encore une fois, il faut des paquets de YAML.

Conclusion

J’ai loupé la séance de questions, parce que je devais aller chercher les bières, mais c’est pas grave, lançons-nous. Docker est un outil un peu chiant, mais très pratique pour les petits ops. Docker est aussi issu d’idées (conteneurs et c-groups) sur lesquels Google bosse depuis …​. des années. Donc forcément, leur outil de gestion de flotte intègre un niveau de complexité supérieur (l’abstraction des pods semble par exemple pratique, mais délicate à aborder). Et évidement, c’est difficile à comprendre pour un non averti comme moi. En revanche, cette complexité permet le déploiement d’outils comme istio, qnui est la killer feature de K8s. Rien que pour donner un exemple, il semble possible pour une entreprise de se débarasser de Dynatrace (dont les licences tournent autour de 100000€/serveur/an). Sans compter toutes les possibilités de debug qui sont, dans le monde des conteneurs, aussi indispensables qu’introuvables. Autrement dit, K8s me tente peu, mais Istio le rend supportable.

L’immutabilité est un effet de bord de la programmation fonctionnelle

Le titre fait un peu tarte à la crème, mais vous allez voir, le raisonnement, s’il risque de heurter l’esprit des mathématiciens, n’en détient pas moins un certain intérêt.

Vous connaissez évidement la programmation fonctionnelle … qu’on réduit malheureusement à flat/map/reduce (mais la page wikipedia montre bien que le domaine est plus vaste). Quant à l’immutabilité, c’est le paradigme, notamment poussé par Erlang, il me semble, qui dit que les variables d’un programme doivent toutes être immutable (c’est-à-dire impossibles à modifier). C’est très chouette … dans certains cas.

L’un des aspects clés de la programmation fonctionnelle, c’est qu’on peut décrire un programme informatique comme une fonction, c’est-à-dire y = f(x), avec

  • x qui est l’espèce de structure magique des valeurs d’entrée, laquelle est évidement multidimensionnelle, et où certaines valeurs sont à leur tour multidimensionnelles.
  • f qui est notre programme
  • y qui est la structure magique des valeurs de sortie, laquelle n’est pas décrite dans le même ensemble de dimensions que x.

Si votre fonction f est pure, tout va bien : x est bien l’ensemble des valeurs d’entrée, et y est bien l’ensemble des valeurs de sortie. Les choses se gâtent si, par exemple, vous voulez … lire depuis un périphérique de stockage ou d’entrée … ou écrire sur un tel périphérique. C’est ce qu’on appelle des effets de bords : ils sont invisibles dans la déclaration de la fonction. Et franchement, sans ces périphériques, votre fonction est joliment pure, mais surtout bien cantonnée dans le monde des idées. Interagir avec le monde réel nécessite donc de rendre votre fonction impure. Et c’est mal.

Maintenant que les termes sont posés, relisons l’énoncé au ralenti.

L’immutabilité est un effet de bord de la programmation fonctionnelle.

C’est louche, hein.

Ce que je veux dire par là, c’est que les gens qui font de la programmation fonctionnelle pensent que l’immutabilité est importante, voire même nécessaire, alors qu’en fait elle découle de la définition pseudo-mathématique d’un programme en tant que fonction. Regardez, dans y = f(x), est-ce que x ou y changent ? Non. Du coup, ils sont immuables. Quel effort ai-je fait pour obtenir ce résultat ? Aucun. Et je vais vous affirmer que c’est absolument indispensable …

Amusant.

D’une manière anecdotique, dans la programmation objet, l’immutabilité est tout autant possible, et tout aussi cool. Le principal inconvénient est que les langages favorisant le style objet n’ont pour l’instant pas encore compris que rendre les objets immuables par défaut pouvait être une bonne idée. Qui plus est, la plupart des outils actuels (ORM & co) n’ont pas vraiment cette idée en tête.

Evidement, ça sonne un peu hérétique comme vision. Du coup, si vous vous sentez attaqué, n’hésitez pas à répondre 😉