Cet article se base sur le talk Microservices: Infinity War! Spring vs MicroProfile que j’ai donné à Devoxx France 2019 avec ma collègue Darren Boutros. |
Microservices : un rien d’histoire et de contexte
On peut voir l’architecture microservices comme une évolution l’architecture SOA (Service Oriented Architecture), elle-même créée pour pallier aux inconvénients des applications monolithiques.
-
Un des points intéressants à remarquer dans la transition SOA vers l’architecture microservices, est la suppression de l’ESB (Enterprise Service Bus).
La communication entre les services devait être la principale fonction de ce composant, mais il embarquait fréquemment une trop grande complexité métier.
Pour corriger cela, il a été remplacé par les endpoints REST des microservices.
Pour illustrer ce changement, Martin Fowler palera de "Smart endpoints and Dumb pipes" -
On constate également que l’on ne travaille plus avec un seul et unique runtime, mais avec 1 runtime par microservice, ce qui participe à garantir une de leurs principales caractéristiques : l'isolation.
par "runtime", il faut entendre serveur (comme Tomcat ou Jetty) |
L’inspiration des microservices
En 2005, Alistair Cockburn présentait l’architecture hexagonale (ou modèle “Ports and Adapters”) afin de permettre la conception d’applications pouvant être testées en isolation de leurs runtimes et bases de données.
Cela a été l’inspiration pour l’architecture microservices, dont Alistair donna ensuite la définition suivante : “An architectural style or an approach for building IT systems as a set of business capabilities that are autonomous, self contained, and loosely coupled”
Architecture hexagonale

Le principe fondateur de ce pattern est que le métier ne doit dépendre de rien : TOUTES les dépendances vont de l’extérieur vers l’intérieur. |
Le but principal de cette architecture ne date pas d’hier, il est question de séparer clairement le métier de l’implémentation technique (notion d'isolation).
-
Tout ce qui se trouve à gauche de l’hexagone représente les composants qui ont besoin de ce dernier.
On trouve côté gauche des interfaces exposées pour les composants ayant besoin d’invoquer le modèle. On parle d'API, pour Application Provider Interfaces.
→ Les composants souhaitant communiquer avec notre métier le feront au travers d’adaptateurs qui contacteront nos API. -
Tout ce qui se trouve à droite de l’hexagone représente les composants dont ce dernier a besoin.
On trouve côté droit des interfaces exposées pour les composants que le modèle a besoin d’invoquer. On parle de SPI, pour Service Provider Interfaces.
→ Les composants avec lesquels notre métier souhaite communiquer seront contactés au travers des SPI dont les implémentations seront résolues à l’exécution et fournies par des adaptateurs.
Isolation

Comme nous le verrons plus en détail par la suite, la notion d'isolation est capitale pour les microservices, or l’isolation amène la redondance, et cette dernière, on nous a appris à la "combattre" depuis des dizaines d’années.
Rappelez-vous le principe introduit dans The Pragmatic Programmer : Don’t Repeat Yourself (DRY).
Prenons le cas de 2 classes partageant un même comportement.
Comme on nous l’a appris en programmation OO, on aura généralement tendance à sortir ce comportement commun dans une classe de plus haut niveau, qui sera ensuite héritée.
Si on change le comportement de la classe mère, on impacte donc les 2 classes filles.
Cet héritage a donc augmenté le couplage entre nos classes.
L’exemple précédent est… juste un exemple pour illustrer un problème classique de couplage 😅 |
Dans le cas des microservices, nous voulons éviter au maximum tout couplage, afin que ces derniers soient le plus indépendants possible. Donc, entre DRY et couplage, et isolation et redondance, la 2nd approche est privilégiée.
DDD et redondance
La conception des microservices plébiscite l’approche DDD (Domain Driven Design). Si vous voulez plus de détails sur ce point, je vous conseille l’excellente conférence Hexagonal at Scale, with DDD and microservices! de Cyrille Martraire, lors du Voxxed Days Microservices Paris 2018. |
Pourquoi les microservices ?
Du fait du développement d’Internet, tout le monde communique avec tout le monde, et est en concurrence avec tout le monde.
L’émergence des microservices est la conséquence de l’évolution de nos applications pour faire face à ces nouveaux besoins :
-
Complexité croissante
Les applications ne se limitent plus au seul data center de la compagnie, mais communiquent avec les services externes d’autres providers sur tout le globe. -
Besoin de livrer de plus en plus vite
Quand la concurrence est partout, il faut pouvoir faire évoluer son produit rapidement, et donc être capable de livrer des nouvelles fonctionnalités au plus tôt, sans devoir attendre de release complète. -
Besoin de performance et de scalabilité
Il faut être capable de s’adapter aux montées en charge d’un marché potentiellement mondial : très vite scaler sur de multiples serveurs, et libérer les ressources tout aussi vite quand le pic de charge est passé. -
Doivent être toujours disponibles
Du fait de la compétition de plus en plus sauvage, si votre application tombe, votre client part chez le concurrent… Votre application doit être résiliente, et être capable de gérer les pannes (on parlera pour cela de "Design for Failures").
Pour adresser ces problématiques, des sociétés comme Netflix, Amazon, eBay commencèrent à casser leurs monolithes en services :
-
de petite taille, chacun ne remplissant qu’une fonction
-
pouvant être déployés indépendamment les uns des autres.
Ces services distribués, petits, simples et découplés permirent aux applications de devenir scalables, résilientes et flexibles.
→ Ils prirent progressivement le nom de microservices.
La découpe des applications monolithiques en microservices est donc le Use Case d’origine des microservices. |
Principaux Use Cases
-
"L’originel (le passé)" : Migration d’un monolithe vers une architecture microservices
-
"L’actuel (le présent)" : Développement d’applications cloud-native
La transition aux applications Cloud-native est bien expliquée dans le Spring Microservices in Action p5 :
You start building microservices because they give you a high degree of flexibility and autonomy with your development teams, but you and your team quickly find that the small, independent nature of microservices makes them easily deployable to the cloud.
Approche Cloud-native

Les microservices sont maintenant l’architecture "par défaut" pour bâtir des applications Cloud-native.
L’approche Cloud-native a les grandes caractéristiques suivantes :
-
Architecture microservices : implique de multiples équipes indépendates, travaillant à l’amélioration du système.
-
Continuous Delivery : Le CD représente un process d’automatisation permettant aux développeurs de déployer rapidement vers les environnements de prodution
-
DevOps : La culture DevOps rapproche développeurs et OPs, et les aide à livrer une meilleure valeur partagée au client.
-
Containerized : La notion de container est capitale, car ce sont ces derniers qui permettent aux applications de pouvoir être déployées n’importe où.
Ce qui importe n’est pas OU ces dernières sont déployées, mais COMMENT elles le sont.
Voici une définition de l’approche Cloud-native que j’aime particulièrement :
Cloud native is an approach for building applications as micro-services and running them on a containerised and dynamically orchestrated platforms that fully exploits the advantages of the Cloud computing model.
On y parle d’exploiter les avantages qu’offre la conception dans le Cloud, afin de répondre aux nombreuses contraintes inhérentes au développement de microservices.
En effet, le développement de ces derniers est complexe, principalement car ils sont nombreux.
On ne développe jamais un mais DES microservices, dont il faut assurer la communication, le cycle de vie, le monitoring, etc etc.
Tout cela nécessite la mise en place d’un environnement complexe, on parlera de capability model.
Ce terme de capability model n’est pas si courant dans la littérature sur les microservices, mais je le trouve très approprié. A la base, je l’ai trouvé dans l’excellent article A capability model for microservices de Rajesh RV, l’auteur de Spring Microservices. |
Capability model
La conception de microservices ne se limite pas au simple code du service lui-même, l’environnement, le capability model comme nommé précédemment, est essentiel.
Faisons apparaître ses "capabilities" progressivement :
Microservice "core"
Rappelons les caractéristiques des microservices :
-
"petits" : comprendre par là qu’ils n’assurent la responsabilité que d’un point précis d’un domaine métier.
-
faiblement couplés : donc indépendants, et devant être déployés indépendamment les uns des autres.
Pour aider à cela, il est préconisé que chaque microservice dispose d’une persistance dédiée. -
distribués
API
Ce dernier va très rapidement devoir communiquer avec d’autres microservices, ce qui se fera au travers d'API.
Service Discovery
Afin que nos microservices puissent se trouver les uns les autres, ils s’enregistrent auprès d’un Service Discovery.
Load Balancer
Dès lor que vous avez plusieurs instances d’un même microservice, vous avez besoin d’un Load Balancer pour distribuer le trafic et la charge.
API gateway
Il faut proposer un point d’entrée unique pour tous vos services.
C’est le rôle L'API gateway, qui, de ce fait, est également le lieu idéal pour implémenter certains aspects transverses comme le routage statique et le routage dynamique.
Par exemple, en fonction de certaines données de la requête arrivante, on dirige une population de beta-testeurs sur une version spécifique de certains services.
Communication entre microservices
Les microservices communiquent entre eux avec un protocole léger et indépendant de leur technologie.
la communication peut être synchrone ou asynchrone.
Synchrone
Implémentée au travers d'appel REST en HTTP.
Ce type de communication est généralement privilégié pour des services externes.
Il est en effet idéal pour des requêtes externes, car permettant de gérer facilement les intéractions temps-réel avec un client.
Néanmoins, son inconvénient est d'augmenter le couplage entre 2 microservices.
Asynchrone
Communication Event Driven, implémentée via la mise en place d’un bus d’évènements (protocoles d’envoi de messages asynchrones AMQP, STOMP, MQTT et outils comme RabbitMQ, ActiveMQ), ou d’un mécanisme de Pub/Sub (Kafka est le roi incontesté de ce domaine…).
Ce type de communication est privilégié pour les échanges relatif à la "mécanique interne" d’une fonctionnalité rendue par un ensemble de microservices (en d’autres termes, la "plomberie", ce qui n’est pas exposé au client)
Dans ces cas, le client n’attend généralement pas de réponse immédiate, voire n’en attend tout simplement pas.
Ces échanges étant plus répandus que les besoins d’intéractions temps réel, la communication asynchrone est la plus fréquemment rencontrée pour les microservices.
Ses avantages sont :
-
meilleur découplage des microservices
Attention toutefois, on peut devenir dépendant (donc re-couplage) de la version du type de message.
Exemple: JSON ne supporte pas nativement le versioning, contrairement à Avro (poussé par Kafka) -
meilleure résilience : le message reste dans la queue même si le consommateur est down.
-
meilleure scalabilité : pas besoin d’attendre une réponse du consommateur du message.
-
meilleure flexibilité : émetteur et consommateur ne se connaissent pas, on peut donc ajouter de nouveaux consommateurs sans impacter l’émetteur.
Côté inconvénients :
-
il faut se méfier de la gestion de l'ordre des messages.
-
debugging plus compliqué : l’exécution n’étant plus linéaire.
Configuration management
Vos microservices étant nombreux, vous n’allez pas gérer la configuration de chacun d’eux séparemment, il va donc falloir centraliser leur configuration.
Design for failure
Les microservices sont des systèmes distribués, pour éviter tout problème de réseau, ou que la défaillance d’un service (ou instance de service) n’impacte les autres, vous devez penser à la résilience de l’application dès sa conception, ce qu’on appelle le Design for failure.
Voici les principaux patterns à mettre en place :
-
circuit breaker : pour éviter que l’on continue d’appeler un microservice défaillant, permet le fail fast.
-
fallback : propose un comportement alternatif en cas de défaillance d’un microservice (exemples : accès à une autre source de données, queueing de la requête, etc.)
-
bulkhead : on sépare les appels aux ressources distantes dans des thread pools différents (pour éviter qu’un service défaillant ne vampirise les ressources)
Logging et tracing
Notre bon vieux monolithe a cédé la place à plusieurs dizaines ou centaines de microservices, en conséquence, la gestion des logs et du tracing est devenue bien plus compliquée.
Chaque microservice a ses propres logs, et une transaction utilisateur peut impliquer plusieurs de ces derniers.
Les patterns suivants permettent de ne pas se noyer dans cette masse de données :
-
log correlation : via un ID de corrélation, permet de suivre les logs d’une transaction entre différents services
-
log aggregation : regroupe toutes les logs en 1 même persistance
-
tracing distribué : permet de visualiser le flux / workflow d’une transaction utilisateur au travers des différents microservices
Sécurité
-
Authentification : permet de savoir QUI veut se connecter à vos services
-
Autorisation : permet de savoir si l’utilisateur, précédemment authentifié, a bien le droit d’entreprendre l’action qu’il souhaite (gestion de droits)
-
Délégation d’accès : pour éviter que le service client n’ait systématiquement à représenter ses credentials pour chacun des services impliqués dans la transaction
Patterns de build et de déploiement
Nos microservices sont nombreux, on ne va pas pouvoir chacun les déployer, ou les redémarrer (gestion de panne), "à la main", d’où la mise en place des patterns suivants :
-
CI/CD : implique la mise en place d’un pipeline de build et de déploiement automatisé.
-
Infrastructure as code : permet de considérer le provisioning des nos services comme du code pouvant être géré par un gestionnaire de sources.
-
Immutable infrastructure : Une fois qu’un service est déployé, l’infrastructure sur laquelle il tourne ne doit plus pouvoir être modifiée par un humain.
Cela renforce la stabilité du système, en garantissant qu’aucune modification ne peut se retrouver en PROD, dans le code déployé, mais nulle part ailleurs…
Implémentation de microservices
Plusieurs stack techniques peuvent être utilisées pour créer nos microservices, et mettre en place le capability model associé.
Les plus connues sont Spring et MicroProfile.
Stack Spring

Au sein de l’écosystème Spring, les projets Boot et Cloud sont ceux permettant d’implémenter des microservices.
Spring Boot
Le but de Spring Boot est de simplifier la création de microservices orientés REST / JSON.
Il permet de créer ceux-ci simplement, au travers d'annotations.
La configuration du build est facilitée via le regroupement des dépendances au sein de "starters" spécifiques (spring-boot-starter-web
, spring-boot-starter-data-jpa
, etc.).
Spring Boot crée des applications stand-alone, ne nécessitant pas d’être lancées au travers d’un serveur d’applications "externe", car embarquant leur propre serveur (Tomcat, Jetty, Undertow).
On parlera d'Uber jars.
Spring Cloud
Le projet Spring Cloud encapsule plusieurs frameworks populaires, assurant des fonctionnalités du capability model des microservices, au sein d’un framework commun. On parle de projet parapluie ("Umbrella" project)
Celui-ci permet de faciliter l’usage et le déploiement de ces technologies, et de les rendre accessibles au travers de simples annotations.
Parmi les projets composant Spring Cloud, on peut citer :
-
Spring Cloud Netflix : intègre la suite Netflix OSS (Zuul, Eureka, Ribbon, Hystrix, etc.)
-
Spring Cloud Consul : intègre Hashicorp Consul (service discovery)
-
Spring Cloud Sleuth : tracing distribué via l’ajout d’un ID de corrélation
-
Spring Cloud Security : framework d’authentification et d’autorisation (OAuth2)
-
Spring Cloud Stream : framework facilitant l’intégration de brokers de message (RabbitMQ, Kafka) pour la communication asynchrone.
Stack Eclipse MicroProfile

Pourquoi la création de MicroProfile ?
MicroProfile s’appuie sur des spécifications venant de JEE (JEE 7 pour les premières versions).
A priori, parlez de JEE ces dernières années pour le développement de microservices semble être synonyme de se tirer une balle dans le pied…
Après tout, JEE est une spécification pour des serveurs d’application dédiés à des applications monolithiques, et l’on a Spring Boot et Cloud sous la main qui sont spécialement conçus pour ce type de développement.
JEE, avec toutes les JSRs de la plateforme complète, semble trop "lourd" pour les microservices :

Fort de ce constat, voyant que Java EE n’arrivait plus à évoluer assez vite face aux changements de l’industrie, et conscients des investissement déjà réalisés dans la technologie, plusieurs entreprises et éditeurs de logiciel (Red Hat, IBM, Tomitribe, Payara), soutenus par la communauté Java, ont décidé de créer MicroProfile, une plateforme optimisée pour l’architecture microservices, basée sur JEE.
Just Enough Application Server (JeAS)
"Just Enough Application Server"… Le nom seul du concept est éloquent.
Historiquement, un serveur d’application, c’était "one size fits all". On n’avait pas le choix, notre application devait tourner sur un serveur incluant toutes les JSRs de la plateforme JEE.
Mais le principe de JeAS est justement d'inverser la relation entre le serveur d’application et l’application, vous permettant de ne packager que les fonctionnalités du serveur d’application requises par votre application.

Les avantages de cette approche sont les suivants :
-
Réduction de la taille de l’application : comparée à la somme d’une application classique PLUS le serveur d’application
-
Réduction de la mémoire allouée : va dépendre du nombre de classes qui n’auront plus besoin d’être chargées
-
Réduction de la surface d’attaque : moins de ports d’ouverts, moins de services qui tournent
-
Meilleure séparation entre les applications : comparé à un serveur d’application dans lequel on avait généralement plusieurs applications de déployées
-
Mises à jour simplifiées : la mise à jour ne concerne plus qu’UNE application
Parmi les runtimes implémentant JeAS, on peut citer RedHat Thorntail (anciennement WildFly Swarm), IBM Open Liberty, TomEE de Tomitribe, et plusieurs autres encore.
Vu comme cela, le principe semble plutôt simple, et avoir beaucoup d’avantage, alors… Mais pourquoi ne pas avoir fait cela avant ?!
→ Tout simplement parce qu’à l’époque, le coût du matériel était bien plus élevé qu’aujourd’hui. Mieux valait donc minimiser le nombre de machines.
De nos jours, avec l’avènement des VM et des containers, le constat n’est plus le même.
Description d’Eclipse MicroProfile

Eclipse MicroProfile crée des spécifications pour des microservices en Java Enterprise, avec le bénéfice que ces derniers soient portables entre runtimes JeAS supportant Eclipse MicroProfile.
Le projet est passé à la fondation Eclipse fin 2016 (MicroProfile v1.0)
Il s’appuyait à la base sur des spécifications venant de JEE 7, et de JEE 8 (Jakarta EE) dans les dernières versions.
Comme expliqué précédemment, la motivation derrière la création de MicroProfile était l’impression de plusieurs éditeurs que l’acteur historique (Oracle) avait du mal à se motiver pour faire évoluer la plateforme.
MicroProfile était là pour redonner une dynamique (3 releases par an) et une architecture moderne (et Oracle a maintenant rejoint l’initiative).
Implémentations de MicroProfile
Voici les différentes implémentations ayant validées le TCK (Technology Compability Kit) pour MicroProfile 3.0 (07/06/2019) :
-
Helidon 1.3.0 (Open Source, poussé par Oracle)
-
Thorntail 2.5.0 (Open Source, poussé par RedHat)
-
Open Liberty 19.0.0.7 (Open Source, poussé par IBM)
-
IBM WebSphere Liberty 19.0.0.7
Celles en train de le passer sont :
-
Quarkus
-
KumuluzEE
-
Payara Server 5.193
-
Payara Micro 5.193
-
TomEE 8.0.0-M4
Le 11/04/2019, Ken Finnigan, co-fondateur et leader de RedHat Thorntail a annoncé que les travaux sur Thorntail 4.x étaient arrêtés au profit du développement de Quarkus, qui en représente l’évolution. Les livraisons de Thorntail 2.x seront poursuivies pendant 18 mois, pendant lesquels ses utilisateurs seront incités à passer sur WildFly ou Quarkus. |
Se faciliter les tests : Consumer Driven Contracts
Comme déjà vu précédemment, une architecture microservices implique rapidement un grand nombre de microservices.
Dès lors, la problématique des tests d’intégration et au-delà, à savoir tous les tests impliquant une communication des microservices entre eux, devient (très) complexe :
-
Nos tests vont invoquer des microservices, qui vont eux-mêmes en invoquer d’autres, qui pourront en invoquer d’autres, et ainsi de suite.
-
Il faudra lancer au préalable tous les microservices impliqués dans nos tests.
En conséquence, nos tests vont :
-
être lents
-
être fragiles, car directement dépendants de la bonne exécution d’autres microservices
Ce constat est à la base du pattern dit du Consumer Driven Contracts (CDC).

Grâce à ce dernier, on va pouvoir réaliser des tests plus simples, mais tout aussi corrects, grâce aux contrats passés entre consommateurs et producteurs :
-
Plus simples car utiisant des mocks → plus besoin de communication REMOTE avec le "vrai" provider, ou possibilité de coder le producteur sans que les clients existent encore.
-
Tout aussi corrects du fait de la garantie apportée par le contrat.
Les contrats sont générés automatiquement, à partir des tests des consommateurs, ou de la documentation, mais peuvent aussi être écrits à la main.


Côté solution permettant la mise en place du CDC, vous pouvez regarder du côté de Spring Cloud Contract, un autre projet "Umbrella" de Spring Cloud (regroupe plusieurs outils facilitant la mise en place du CDC) |
Cartographie des outils du capability model
Cette section est juste une présentation d’un outil que j’adore : le Cloud Native Interactive Landscape (https://landscape.cncf.io/) de la CNCF (Cloud Native Computing Foundation).
Il s’agit ni plus ni moins que d’une cartographie dynamique (vous pouvez en changez le contenu affiché à l’aide d’un jeu de filtres) des différents éléments / outils composant une application Cloud Native.
Et comme nous avons vu précédemment que les microservices sont devenus l’architecture par défaut pour bâtir des applications Cloud-Native, à l’aide de la cartographie précédente, nous disposons d’un moyen très pratique de lister un grand nombre d’outils du capability model.
Si par exemple je choisis Coordination & Service Discovery à partir du landscape non filtré, les éléments suivants me sont retournés :

Tout simplement génial, non ? 😉
Conseil 1 : faites attention aux catégories !
Dans l’exemple précédent, certains diront sûrement : "Hein ?! Y a pas Consul dans les outils de service discovery ?!!" La raison est toute simple, Consul a tout simplement été rangé dans une autre catégorie. Il faut bien se dire que certains outils remplissant plusieurs fonctions, les classer par catégorie devient rapidement compliqué et subjectif. |
Conseil 2 : prenez votre temps !
La cartographie étant volumineuse, il y a souvent de la latence dans son utilisation. |
Kubernetes et Istio, l’avenir des microservices ?
Pour le moment, avec les stacks Spring et MicroProfile, on pourrait dire que l’on a vu la façon "classique" d’implémenter des microservices : on commence par coder nos services, puis on ajoute progressivement à notre code les appels vers les éléments du capability model.
Tout bien pesé, ces éléments du capability model ne sont finalement que de la "plomberie" nécessaire à notre architecture microservices, le code "métier" se trouvant lui au niveau du "core" de nos microservices.
Aussi, avec cette façon de faire "classique", nous mélangeons, nous couplons, notre métier avec notre plomberie.
Ne pourrait-on pas faire autrement ?
C’est ce que propose l’écosystème Kubernetes via son service mesh Istio.

Qu’est-ce qu’un service mesh ?
Un service mesh est une infrastructure décentralisée, distribuée, entre vos services, qui rend la communication entre eux plus stable et plus fiable. Le service mesh n’est bien sûr valable que pour des applications Cloud-Native, ici impliquant Kubernetes comme orchestrateur. |
Le principe est le suivant :
Kubernetes, en tant qu’orchestrateur, est responsable de l’instanciation des containers.
En architecture microservices, la pratique est d’avoir 1 container par microservice.
En conséquence, Kubernetes va également devenir "l’orchestrateur de vos microservices" : c’est lui qui va les instancier.
Il est donc idéalement placé pour ajouter à ces derniers un ensemble de fonctionnalités en améliorant la fiabilité, le support, la maintenance… Vous l’avez compris, il s’agit des fonctionnalités du capability model.
Pour ajouter ces différentes fonctionnalités, Kubernetes va se reposer sur le service mesh Istio.
On ajoute le support d’Istio aux microservices en déployant, pour chacun d’eux, un sidecar proxy qui va intercepter toutes les communications entre eux.
Tous ces sidecar proxy sont rattachés à Istio, qui va pouvoir les configurer et les gérer, afin qu’ils puissent ajouter à leur service associé, les fonctionnalités souhaitées disponibles dans Istio (service discovery, load balancing, règle de routage, gestion des erreurs, authentification / identification, etc.).
Au final, nous avons déplacé toutes les préoccupations de communication des applications en dehors du domaine métier, dans un sidecar proxy.
Tout n’est qu’un éternel recommencement ?
Reprenons la conclusion précédente : "nous avons déplacé toutes les préoccupations de communication des applications en dehors du domaine métier"
Nous avons donc séparé "le métier" de tout le côté "plomberie".
Plomberie facilitée par le couple Kubernetes / Istio qui décharge grandement le développeur de sa gestion.
→ Nous avons permis au développeur de se concentrer quasi uniquement sur le métier.
Mais, ceci n’était-il pas déjà la promesse avancée par… JEE (Java Enterprise Edition) ?
Le développeur s’occupe du code métier, et le serveur d’application s’occupe de toute la plomberie.
Ce serveur d’application "honni", synonyme de "vieilles" applications monolithiques, avec toutes ses JSRs embarquées… Ne sommes-nous pas en train de le remplacer par une version plus flexible et distribuée (Kubernetes / Istio), mais, finalement, dans les services rendus, pas si éloignée ?
Au final, on pourrait voir Kubernetes / Istio comme une simple "mise au goût du jour" d’un concept vieux de 20 ans 😉
Conclusion
Au travers de cet article, nous avons pu voir d’où provenaient les microservices, quels étaient les nouveaux besoins, et les nouvelles solutions ayant conduit à leur création.
Nous avons également montré que la complexité des microservices venait, non pas du code des services eux-mêmes, mais de la mise en place de l’environnement technique associé (capability model).
Plusieurs stack techniques existent pour mettre en place ce dernier, Spring et MicroProfile étant les plus connues.
Néanmoins, l’arrivée de Kubernetes / Istio, avec les avantages proposés par son usage du sidecar proxy, va peut-être d’ici peu changer ce constat (si ce n’est déjà fait).
Le clin d’oeil de fin vient de notre bon vieux serveur d’application, que certains disent déjà mort et enterré, mais vis à vis duquel Kubernetes / Istio pourrait finalement être vu comme une simple évolution 😉