Le loueur européen de véhicules Sixt a mis au point une API de mise en œuvre d’une architecture MSA de micro-services, particulièrement intéressante, que tous les chefs de projet devraient regarder de près, tant elle est symbolique de ce que l’on devrait pouvoir faire dans ce domaine.

 

Conscient de ce que Oracle ne fait pas grand-chose dans le monde des MSA (Micro-Services Architecture), la compagnie allemande Sixt a « pris le taureau par les cornes » et a développé sa propre pile d’API ja-micro, pour construire, déployer et exécuter des micro-services écrits en Java ou en Go. Cette bibliothèque déposée dans GitHub est disponible sous licence Apache.

L’objectif de Sixt, que l’on n’attendait pas à pareille fête, était d’exploiter les API existantes les plus pertinentes et de développer ainsi ses propres applications, qui au moins en théorie, devait bénéficier des qualités de ce type d’applications : performances, résilience, simplicité de maintenance, adaptabilité, etc.

Elle nous semple exemplaire dans la mesure où l’on comprend mieux les problèmes qu’ont et qu’auront à résoudre les chefs de projets MSA, à partir du moment où le modèle d’enchaînement de micro-services aura été imaginé, ce qui est quand même le principal écueil de ce type d’architecture. Avec une complexité encore plus grande qu’avec les SOA, car les services sont d’une granularité plus fine, ce qui induit une orchestration encore plus délicate à mettre au point.

Sixt a réussi à construire une plate-forme de développement de micro-services, un exemple à suivre…
Des micro-services écrits en Java ou Go

Du point de vue langage, Sixt laisse le choix à ses utilisateurs entre Java et Go de Google (un langage qui monte), selon la nature fonctionnelle des micro-services, mais aussi le « feeling » des développeurs, micro-services qu’il veut compatibles. A priori, si les chefs de projets préfèrent un autre langage, Six ne les bloquera pas, au contraire il assurera leur intégration, via l’API Go Micro, qui est une sorte de proxy de micro-services.

Chacun des micro-services sera intégré dans un container Docker, mais d’autres possibilités sont envisageables. Une simple archive JAR Java par exemple.

Une fois que les micro-services auront été écrits, il faudra les enregistrer de manière à ce qu’on puisse ensuite en retrouver la trace et les invoquer.

Ce travail est fait par un « registry » que Sixt a mis au point, qui comporte toutes les informations d’un annuaire de services, en particulier les formats de sollicitation. De sorte qu’à l’exécution, après avoir modélisé l’enchaînement des micro-services, chacun d’eux pourra solliciter le « registry » pour connaître l’URL de connexion et la manière de se connecter aux autres micro-services. C’est un peu la même idée que pour les SOA avec l’annuaire UDDI ou JNDI Java.

Pour solliciter un autre micro-service, ja-micro fonctionne en mode RPC. Il faut d’abord instancier la classe RpcClientFactory, ce qui nous donne un objet client RpcClient, qui va se charger de toute la mécanique liée à un processus RPC : l’appel du service à distance par une méthode callSynchronous (bientôt il y aura aussi une méthode asynchrone), les data étant formatées en mode protobuf, qui est une sorte de sérialisation des données (préféré à XML), mais aussi la gestion des « time-out », les retry, la gestion des erreurs via la classe RpcCallException, etc.

Ja-micro comporte par ailleurs un mécanisme de « heartbeating », qui permet de renseigner le « registry » toutes les x secondes de l’état de santé de chacun des micro-services, avec des moyens pour intervenir sur cet état. Histoire à l’exécution de solliciter un micro-service en bon état, capable de faire son travail et le cas échéant de basculer sur un autre service en attente, après avoir envoyé un message à l’administrateur.

Ce système sera très utile, qui obligera à se poser les bonnes questions (dans le code) quant au fonctionnement de l’application et éventuellement de son mode dégradé, au cas où se produiraient des dysfonctionnements.

C’est sur ce même mécanisme de registry qu’est fondé le load-balancing.

Tout au long de l’activité de l’application, un système de logging permet d’enregistrer les événements au format JSON JavaScript, les logs pouvant être personnalisés.

Diffusion et tests des services

Pour traiter le problème de la diffusion des micro-services dans leur environnement Docker, sur chaque nœud de traitement des micro-services, Sixt a opté pour 2 frameworks bien connus : Guice pour la mise en œuvre, qui comporte en particulier une interface pour relier les différents micro-services, le cœur de toute l’architecture et traiter les erreurs courantes d’adressage, mais aussi Kafka pour la gestion des événements. La gestion des dépendances, elle, est prise en charge par Guice.

La migration des bases de données

Pour migrer automatiquement des données qui peuvent être portées par des bases différentes, Sixt a retenu l’excellente API Flyway, particulièrement simple à utiliser, qui est capable de migrer à peu près tout ce qui a une connotation SQL de base de données relationnelle. La migration pouvant être codée soit par des scripts SQL, ce qui sera sans doute la manière la plus simple, soit en Java. Sur le principe, Flyway est surtout utilisé dans des contextes de livraison continue, le déploiement d’un micro-service étant une forme de livraison de ce type.

Un empilage exemplaire

L’empilement qu’a imaginé Sixt a plusieurs vertus :

  • il est un exemple concret de mise en œuvre d’une architecture de micro-services
  • il précise les différents aspects techniques qu’il faut traiter dans cet environnement
  • il prouve qu’il existe en Open Source (mais c’est vrai aussi pour le monde propriétaire) des API susceptibles de répondre aux problèmes
  • il met l’accent sur la technicité de ce type de développement avec le risque de s’embarquer sur des solutions complexes, qui nécessiteront de prendre les chefs de projets en otages (…), tant ils seront indispensables

Sans doute conscient de ce qu’il s’aventure dans des domaines peu balisés, Sixt accepterait volontiers l’aide de contributeurs externes. Histoire de constituer une sorte de communauté Open Source, qui serait la meilleure garantie de pérennité pour sa plate-forme.