Une vision sur le Service Mesh : Service Mesh versus librairies applicatives ? : l’exemple de Spring Cloud
Cette année les Services Mesh sont de toutes les conférences : istio, linkerd, kubeflix, zuul ?... Dans un premier article nous avons positionné le Service Mesh et ses enjeux dans l’écosystème des microservices. Dans le second nous avons proposé une radiographie des fonctionnalités d’un Service Mesh et des fonctionnalités connexes. Nous étudierons ici quel recouvrement peut exister avec un framework applicatif comme Spring Cloud.
Le Service Mesh est un concept relativement jeune mais ces fonctionnalités fondamentales (routage, sécurisation, load balancing) sont très classiques.
Alors s’agit-il d’une énième amélioration de fonctionnalités existantes à l’image de cette brouette à deux roues ? Ou s’agit-il d’un nouvel outil qui nécessite de repenser la façon de procéder, à l’image de l’usage d’une tronçonneuse en passe de remplacer la hache ?
Pour y répondre nous allons chercher à répondre à ces fonctionnalités de façon entièrement applicative.
Au niveau développement applicatif il est toujours possible à partir des briques les plus élémentaires de réimplémenter tous les patterns. Ce qui va nous intéresser ici est d’identifier quelles plateformes, quels frameworks fournissent déjà des briques pré-packagées pour implémenter ces fonctionnalités d’un point de vue applicatif.
Composant | Description | Patterns implémentés |
Zuul est une passerelle de services (Service Gateway) permettant du routing dynamique, du monitoring, de la résilience et de la sécurité https://github.com/Netflix/zuul Spring est en train de l’augmenter dans le projet Spring Cloud Gateway https://cloud.spring.io/spring-cloud-gateway/ | Zuul est une gateway bâtie sur un ensemble de filtres en Java. L’utilisation d’un langage de programmation permet de mettre autant de logique de routage dynamique que souhaitée dans ces filtres. Cela constitue le différenciant majeur de cette brique.<br><br>Cependant, il est déconseillé de mettre de la logique métier à ce niveau. Zuul expose la configuration des routes sous la forme de ressources REST ce qui rend son paramétrage dynamique.<br><br>Étant une gateway HTTP, elle reste technology agnostic.<br><br>N’étant pas conçue autour des API REST, elle sera moins adaptée qu’une API Management pour l’exposition de documentation. | Zuul intègre les composants Hystrix, Ribbon, Turbin et Archaius au sein de la gateway ce qui le conduit à agréger l’ensemble de leurs patterns tout en restant technology agnostic (au protocole HTTP près).<br><br>Le cœur de Zuul est cependant une passerelle de routage.<br><br>Note : Est-ce que des services comme AWS Route 53 auto-naming ou leurs équivalents ne sont pas des alternatives viables pour remplacer Zuul désormais ? |
Eureka<br><br>est un service registry qui permet d’enregistrer des services et ainsi d’assurer un load balancing entre les services.<br><br>https://github.com/Netflix/eureka | Une librairie Java intégrée à Spring permet aux microservices de s’enregistrer dans Eureka et pour le microservice consommateur de découvrir l’URL adéquate. Le routage est à la charge du consommateur. La librairie Ribbon est la brique correspondante qui a été pensée dans la stack Spring pour ce besoin. | Eurêka contribue donc aux patterns de choregraphy et de load balancing |
Ribbon est une librairie de communication interprocessus.<br><br>https://github.com/Netflix/ribbon | Ribbon est une librairie client intelligente basée sur un modèle asynchrone et réactif. Son usage principal reste cependant celui d’une librairie client pour des appels REST. Elle réalise du load balancing. | Ribbon contribue donc aux patterns choregraphy et load balancing et canary release en fournissant un contrôle fin du routage du trafic |
Feign est une librairie cliente qui outille les appels REST<br><br>https://github.com/OpenFeign/feign | Son principal intérêt est son intégration avec les librairies Ribbon et Hystrix. | En elle-même, elle ne répond à aucun pattern directement. Mais est utilisée comme un composant au sein d’autres librairies. |
Hystrix est une librairie assurant les fonctionnalités de Circuit Breaker et de Bulkhead notamment<br><br>https://github.com/Netflix/Hystrix | Hystrix possède plusieurs modes de fonctionnement. L’un de ceux-ci isole les appels clients dans des threads séparés. C’est ce qui confère à cette librairie des propriétés de bulkhead.<br><br>Il implémente la machine à état d’un Circuit Breaker. Enfin il permet de mettre en attente des requêtes HTTP - ce qui porte le nom de Request Queuing. Il peut ensuite les émettre de façon groupée ce qui porte le nom de Request Collapsing. | Hystrix implémente donc les patterns Circuit Breaker, Bulkhead, Request Queuing et Request Collapsing. |
En synthèse, la stack applicative Spring Cloud permet de mettre en œuvre les patterns applicatifs et techniques du Service Mesh. Son excellente intégration avec la stack Spring fait qu’il est extrêmement facile de d’évoluer d’un découpage en composants applicatifs en un découpage en microservices. Cependant, ces technologies sont très couplées aux stacks Java et Spring ce qui nécessite une bonne connaissance de ces technologies dans l’équipe. Nous vous recommandons donc d’utiliser ces briques comme pont entre une application java cloud native et le reste de votre écosystème.
Pour d’autres patterns, des librairies existent également.
La partie analytics tirera parti d’un développement applicatif avec l’outil comme simpleclient de Prometheus. Son intégration à Spring Boot pourra fournir des librairies génériques, mais pour accéder à des données réellement métier, le développement de métriques au sein de l’application reste indispensable.
Le pattern consumer driven contract peut être outillé avec la librairie Spring Cloud Contract.
La documentation de l’API peut être générée à partir de Spring RestDocs qui se base sur des annotations sur les tests de façon à ce que la documentation reste en permanence validée par ces derniers.
Le feature flipping peut être outillée avec la librairie ff4j qui fournit également une bonne intégration à Spring.
L’intégration des tâches d’administration au démarrage de l’application peut être mise en oeuvre en utilisant des outils (comme Flyway) qui permettront de s’assurer que le schéma de la base de données est toujours cohérent avec la version de l’application.
Spring Cloud Config fournit le support côté client et côté serveur d’une solution de configuration distribuée. Très bien intégrée côté client à la configuration de Spring, cette solution peut se révéler en concurrence avec un service comme Consul mis en place côté infrastructure.
Spring Cloud Sleuth permet d’annoter le code pour que l’identifiant de corrélation requis par le distributed tracing soit propagé là où il ne le serait pas par défaut.
Spring Security assure la partie client d’OAuth2 et OIDC et MITREid est un exemple d’implémentation de provider OIDC.
Enfin un certain nombre de patterns restent peu ou pas outillés. La scalabilité par process nécessite une conception applicative qui évite tout état (pas de session HTTP, aucune donnée de portée globale…).
L’idempotence et le pattern de tolerant readers sont également peu outillés et reposent principalement sur de bonnes pratiques de code.
Pour le log centralisé, la recommandation la plus courante consiste à logger dans la console et à laisser la stack sous-jacente assurer la collecte.
Les portails d’API Management n’ont pas de raison d’être implémentés spécifiquement car ils constituent un applicatif générique qui n’est pas différenciant pour un métier. Si un portail complet (au delà des fonctionnalités de documentation de Spring REST Docs) est nécessaire dans votre architecture il faudra donc compléter la stack Spring Cloud par un portail d’API Management.
Enfin, les fonctionnalités d’infrastructure comme les conteneurs, l’orchestration de conteneurs et le SDN ne seront également jamais implémentés de façon applicative.
Le schéma suivant positionne ces différentes briques dans le cadre précédent.
La couche applicative permet donc d’implémenter un grand nombre de ces fonctionnalités. Certaines d’entre elles seront plus facilement réalisées avec des outils dédiés. Pour d’autres le choix est quasi neutre. L’implémentation applicative correspond au choix du sur-mesure fait par les géants du web car il s’adapte au plus près des besoins. Cependant, ces librairies ont été conçues à une époque ou d’autres outils n’existaient pas encore. Certaines de ces briques peuvent donc être aujourd’hui concurrencées par des produits sur étagère plus récents, et notamment les outils de Service Mesh comme linkerd ou istio.
Alors comment choisir ? Il faut garder en tête que les outils que l’on maîtrise apparaissent naturellement plus répandus et plus faciles à utiliser. Cette série d’articles a pour objectif de vous donner un cadre de lecture le plus limpide possible pour comparer les fonctionnalités apportées par chacune des briques et éclairer votre choix. Celui-ci met bien sûr l’accent sur Spring Cloud pour en voir les possibilités mais également mieux le challenger.
Le principal caractère disruptif des outils de Service Mesh repose selon moi sur le caractère décentralisé de son implémentation - approche side-car - contrairement aux outils précédents. L’approche side-car consiste à positionner un second processus, accroché au processus applicatif comme un side-car est accroché à un moto. Celui-ci joue un rôle de proxy sur le trafic réseau et implémente la majorité des fonctionnalités du Service Mesh. Cette approche est le plus souvent globale. Tous les outils comme linkerd ou istio font l’hypothèse que tous les microservices vont les utiliser !
En termes de microservices, cela revient à partager une stack technologique. Si vous faites ce choix d’une stack globale : considérez-le comme un choix d’entreprise. Celui-ci s’impose aux microservices. Ceux-ci n’auront donc plus totalement la liberté des technologies qu’ils utilisent, en contrepartie de fonctionnalités disponibles sur étagère.
Sources des illustrations : https://pixabay.com/fr/brouette-b%C3%A2timent-la-construction-1296942/ https://pixabay.com/fr/brouette-chariot-de-jardin-31876/ https://pixabay.com/fr/hache-chopper-outil-2027029/ https://pixabay.com/fr/scie-%C3%A0-cha%C3%AEne-outil-%C3%A9quipement-vu-304333/