Il y a eu récemment beaucoup de débats à propos de la mise en oeuvre de micro-services comme approche pour créer des applications basées sur les concepts de l'architecture orientée services. En parallèle, il y a eu une vague de consternation liée au fait que l'industrie avait encore besoin d'un nouveau mot-clé à la mode et de nombreux débats pour déterminer si les micro-services étaient si éloignés de SOA. Au delà de cette contreverse de nomenclature, l'approche semble gagner du terrain.
C'est une chose de créer une application à base de micro-services en partant de zéro. Cela en est une toute autre de refactoriser l'architecture d'une application déjà en production. C'est exactement ce que la société Karma est en train de réaliser et Stefan Borsje, Directeur technique et co-fondateur de Karma a récemment partagé leur expérience de migration vers une architecture à base de micro-services. Tout en gagnant du point de vue de la séparation des responsabilités, de l'isolation et de la tolérance à la panne, la migration vers des micro-services a amené quelques challenges techniques en termes de tests et de gestion des erreurs.
Karma fournit des modems Wi-Fi prépayés qui permettent de se connecter à internet en 4G. Le système d'information Karma fournit de nombreuses fonctionnalités métier telles que les commandes en ligne, la gestion des appareils, la gestion des commandes et le support utilisateurs. Ces fonctionnalités sont exposées au monde extérieur par l'intermédiaire d'applications web et d'applications mobiles.
L'architecture initiale de Karma était une application monolithique basée sur Rails. Le principal défi était lié au fait que différentes parties du système devaient être distribuées à différents niveaux. L'application gère des appareils, des utilisateurs et une boutique. Parce que les fonctionnalités sont différentes et parce qu'elles se développent de manière indépendante, les services chargés de gérer les appareils et les utilisateurs doivent être capables de grossir plus vite que la partie boutique.
D'autres avantages liés aux micro-services sont une bonne séparation des responsabilités, une meilleure isolation entre les différentes parties de leur code et une plus grande flexibilité dans l'implémentation des différents éléments du système. Karma peut utiliser plusieurs versions de Ruby/Rails dans différentes parties de l'application sans impacter le système dans son ensemble. Ils pourraient, dans le future, être amenés à utiliser d'autres langages et d'autres frameworks en fonction de leurs besoins. Les micro-services aident aussi les développeurs à conceptualiser chaque partie de l'application et permettent d'améliorer leur productivité.
Karma a choisi l'approche incrémentale pour migrer vers des micro-services. En partant d'un monolithe, ils ont extrait des composants fonctionnels au fur et à mesure. L'expérience acquise préalablement à l'utilisation et à la création de l'application les a aidé à faire les bons choix dans la décomposition du système. La décomposition a ensuite continué en redécoupant certains des services nouvellement créés en composants plus légers. Par exemple, la première décomposition a engendré un micro-service "boutique" qui par la suite a été à nouveau décomposé en "commandes", "traitement des commandes" et "suivi". Cette évolution a ensuite continué durant environ une année et demi et est toujours en cours. Stefan explique que le développement de chaque partie dure d'une journée à une semaine pour passer de rien à la production, selon la difficulté.
La décomposition intervient sur l'ensemble du stack applicatif jusqu'à la base de données. Chaque service qui a besoin d'une base de données dispose de sa propre base de données. Chaque micro-service choisit ce qu'il expose.
Décomposer une application monolithique implique une bonne coordination entre les nouveaux composants. Ainsi, les micro-services peuvent aussi bien être destinés à un usage interne qu'à l'extérieur. En arrière plan, Karma utilise principalement deux patterns pour gérer l'interaction entre les micro-services. Les interactions de type requête/réponse sont gérées par le protocole HTTP. Mais il existe aussi des interactions de type publication/souscription qui sont gérées à l'aide de SNS (Standard Notification Service) et de SQS (Simple Queue Service) de chez Amazon. SQS est utilisé pour centraliser les publications et les transmettre aux queues des différents services. Comme Stefan nous l'explique :
Tout cela se résume à savoir si le service est en train de demander ou de parler. Si le service est en train de demander, il a probablement besoin d'une réponse, s'il est simplement en train de parler, il n'aura probablement pas besoin d'une réponse - simplement fire and forget.
N'importe quel retour d'expérience inclut des "défis". Karma a relevé que les tests de bout en bout se révélaient beaucoup plus compliqués à mettre en oeuvre. D'autre part, il est beaucoup plus compliqué de trouver la cause mère des différents problèmes dans la chaîne de cause à effet. Certains commentaires de l'article sous-entendent que le problème pourrait être beaucoup plus lié au messaging asynchrone qu'à l'architecture orientée micro-services.
Une manière de gérer ce problème est de s'assurer que les micro-services adhèrent à un contrat et de concevoir les tests en fonction de ce contrat. Mais Stefan a expliqué que les contrats étaient pour le moment implicites, ce qui rendait les tests difficiles à automatiser. Un des commentaires de Gil Peeters recommande d'utiliser un framework de tests basés sur les contrats orientés consommateur appelé Pact.
C'est un droit de passage pour une société de migrer ses applications pour supporter la montée en charge - la scalabilité horizontale et différentielle - et les micro-services sont devenus une manière populaire de le faire. Indiquez-nous si vous avez une expérience à nous faire partager, qu'elle soit positive ou négative.