Dans ce guide, vous apprendrez ce que sont les microservices Java, comment les concevoir et les créer. Il couvre également des questions sur les bibliothèques de microservices Java et la faisabilité de l'utilisation des microservices. Traduction et adaptation des microservices Java : un guide pratique .
Microservices Java : bases
Pour comprendre les microservices, vous devez d’abord définir ce qu’ils ne sont pas. N'est-ce pas un « monolithe » - Monolithe Java : qu'est-ce que c'est et quels sont ses avantages ou inconvénients ?Qu’est-ce qu’un monolithe Java ?
Imaginez que vous travaillez pour une banque ou une startup fintech. Vous fournissez aux utilisateurs une application mobile qu’ils peuvent utiliser pour ouvrir un nouveau compte bancaire. Dans le code Java, cela entraînera la présence d'une classe de contrôleur. En simplifié, cela ressemble à ceci :
@Controller
class BankController {
@PostMapping("/users/register")
public void register(RegistrationForm form) {
validate(form);
riskCheck(form);
openBankAccount(form);
// etc..
}
}
Vous avez besoin du contrôleur pour :
- Confirmé le formulaire d'inscription.
- Vérification des risques liés à l'adresse de l'utilisateur pour décider de lui fournir ou non un compte bancaire.
- J'ai ouvert un compte bancaire.
BankController
sera regroupée avec le reste de vos sources dans un fichier bank.jar ou bank.war pour le déploiement - il s'agit d'un bon vieux monolithe contenant tout le code nécessaire au fonctionnement de votre banque. À titre d'estimation approximative, la taille initiale d'un fichier .jar (ou .war) sera comprise entre 1 et 100 Mo. Vous pouvez désormais simplement exécuter le fichier .jar sur votre serveur... et c'est tout ce que vous devez faire pour déployer votre application Java. Image, rectangle en haut à gauche : déploiement d'une banque mono(lithique) java -jar bank.jar (cp .war/.ear dans le serveur d'applications). Rectangle droit : ouvrez le navigateur.
Quel est le problème avec les monolithes Java ?
Il n’y a rien de mal en soi avec les monolithes Java. Cependant, l'expérience a montré que si dans votre projet :- De nombreux programmeurs/équipes/consultants travaillent...
- ...sur le même monolithe sous la pression de clients aux exigences très vagues...
- d'ici quelques années...
Comment réduire la taille d’un monolithe Java ?
Une question naturelle se pose : comment réduire la taille du monolithe ? À l'heure actuelle, votre bank.jar s'exécute sur une JVM, un processus sur un serveur. Ni plus ni moins. Et maintenant, une pensée logique peut me venir à l’esprit : « Mais le service de vérification des risques peut être utilisé par d’autres services de mon entreprise ! Ce n'est pas directement lié à mon application bancaire monolithique ! Peut-être devrait-il être découpé dans le monolithe et déployé en tant que produit distinct ? Autrement dit, techniquement parlant, il s’agit d’un processus Java distinct.Qu'est-ce qu'un microservice Java ?
En pratique, cette phrase signifie que désormais l'appel de méthoderiskCheck()
ne sera plus effectué depuis BankController : cette méthode ou composant bean avec toutes ses classes auxiliaires sera déplacé vers son propre projet Maven ou Gradle. Il sera également déployé et placé sous contrôle de version indépendamment du monolithe bancaire. Cependant, l'ensemble de ce processus d'extraction ne transforme pas votre nouveau module RiskCheck en un microservice en soi, puisque la définition d'un microservice est sujette à interprétation. Cela conduit à des échanges fréquents au sein des équipes et des entreprises.
- Est-ce que 5-7 classes sont dans un projet micro ou quoi ?
- 100 ou 1000 cours... toujours du micro ?
- Le microservice est-il généralement lié au nombre de classes ou non ?
- Appelons microservices tous les services déployés séparément, quelles que soient leur taille ou les limites de leur domaine.
- Réfléchissons à la manière d'organiser la communication interservices. Nos microservices ont besoin de moyens de communiquer entre eux.
Comment établir la communication entre les microservices Java ?
En général et en général, il existe deux options : la communication synchrone et asynchrone.Communication synchrone : (HTTP)/REST
En règle générale, la communication synchronisée entre les microservices s'effectue via des services de type HTTP et REST qui renvoient XML ou JSON. Bien sûr, il peut y avoir d'autres options - prenez au moins les tampons de protocole Google . Si vous avez besoin d'une réponse immédiate, il est préférable d'utiliser la communication REST. Dans notre exemple, c’est exactement ce qu’il faut faire, puisqu’une vérification des risques est requise avant l’ouverture d’un compte. S’il n’y a pas de contrôle des risques, il n’y a pas de compte. Nous discuterons des outils ci-dessous, dans la section « Quelles bibliothèques sont les meilleures pour les appels Java REST synchrones ».Messagerie - Communication asynchrone
La communication asynchrone par microservice est généralement réalisée en échangeant des messages avec une implémentation JMS et/ou en utilisant un protocole tel qu'AMQP . Nous avons écrit « généralement » ici pour une raison : disons que le nombre d’intégrations email/SMTP ne peut pas être sous-estimé. Utilisez-le lorsque vous n'avez pas besoin d'une réponse immédiate. Par exemple, l’utilisateur clique sur le bouton « acheter maintenant » et vous souhaitez à votre tour générer une facture. Ce processus ne devrait certainement pas avoir lieu dans le cycle demande-réponse d'achat de l'utilisateur. Nous décrirons ci-dessous quels outils sont les meilleurs pour la messagerie Java asynchrone .Exemple : appel d'API REST en Java
Supposons que nous choisissions la communication synchrone par microservice. Dans ce cas, notre code Java (celui que nous avons présenté ci-dessus) à bas niveau ressemblera à ceci. (par bas niveau, nous entendons ici le fait que pour la communication par microservices, des bibliothèques clientes sont généralement créées pour vous abstraire des appels HTTP réels).
@Controller
class BankController {
@Autowired
private HttpClient httpClient;
@PostMapping("/users/register")
public void register(RegistrationForm form) {
validate(form);
httpClient.send(riskRequest, responseHandler());
setupAccount(form);
// etc..
}
}
Sur la base du code, il devient clair que nous devons maintenant déployer deux (micro) services Java, Bank et RiskCheck. En conséquence, nous aurons deux processus JVM en cours d’exécution. C'est tout ce dont vous avez besoin pour développer un projet de microservices Java : créez et déployez simplement des morceaux plus petits (fichiers .jar ou .war) au lieu d'un seul monolithique. La réponse à la question reste floue : comment découper le monolithe en microservices ? Quelle doit être la taille de ces pièces, comment déterminer la bonne taille ? Allons vérifier.
Architecture des microservices Java
En pratique, les entreprises développent des projets de microservices de différentes manières. L'approche dépend si vous essayez de transformer un monolithe existant en un projet de microservices ou si vous démarrez le projet à partir de zéro.Du monolithe aux microservices
L’une des idées les plus logiques consiste à extraire des microservices d’un monolithe existant. Notez que le préfixe « micro » ici ne signifie pas réellement que les services extraits seront vraiment petits ; ce n'est pas nécessairement le cas. Examinons le contexte théorique.Idée : diviser le monolithe en microservices
Une approche microservice peut être appliquée aux projets existants. Et c'est pourquoi:- Le plus souvent, ces projets sont difficiles à maintenir/modifier/étendre.
- Tout le monde, des développeurs à la direction, souhaite la simplification.
- Vous avez des limites de domaine (relativement) claires, ce qui signifie que vous savez exactement ce que votre logiciel doit faire.
- Il serait donc raisonnable de séparer le traitement des données utilisateur (telles que les noms, adresses, numéros de téléphone) dans un microservice distinct « Gestion des comptes ».
- Ou le "Risk Checker Module" susmentionné qui vérifie les niveaux de risque de l'utilisateur et peut être utilisé par de nombreux autres projets ou même départements de l'entreprise.
- Ou encore un module de facturation qui envoie les factures au format PDF ou par mail.
Mise en œuvre d’une idée : laisser quelqu’un d’autre le faire
L'approche décrite ci-dessus convient parfaitement aux diagrammes papier et de type UML. Pourtant, tout n’est pas si simple. Sa mise en œuvre pratique nécessite une préparation technique sérieuse : l'écart entre notre compréhension de ce qu'il serait agréable d'extraire d'un monolithe et le processus d'extraction lui-même est énorme. La plupart des projets d'entreprise atteignent un stade où les développeurs ont peur, par exemple, de mettre à niveau une version d'Hibernate vieille de 7 ans vers une version plus récente. Les bibliothèques seront mises à jour en même temps, mais il existe un réel danger de casser quelque chose. Ces mêmes développeurs doivent donc désormais fouiller dans du code ancien avec des limites de transaction de base de données peu claires et extraire des microservices bien définis ? Le plus souvent, ce problème est très complexe et ne peut être « résolu » sur un tableau blanc ou lors de réunions d’architecture. Pour citer le développeur Twitter @simonbrown : je le répéterai encore et encore... si les gens ne peuvent pas construire correctement des monolithes, les microservices ne seront d'aucune aide. Simon BrunProjet à partir de zéro basé sur une architecture de microservices
Dans le cas de nouveaux projets Java, les trois points numérotés de la partie précédente semblent légèrement différents :- Vous commencez avec une table rase, il n’y a donc pas de « bagage » à entretenir.
- Les développeurs aimeraient garder les choses simples à l'avenir.
- Problème : Vous avez une image beaucoup plus floue des limites de domaine : vous ne savez pas ce que votre logiciel est réellement censé faire (indice : agile ;))
Architecture technique des microservices
Le premier point semble être le plus évident pour les développeurs, mais il y a aussi ceux qui le déconseillent fortement. Hadi Hariri recommande le refactoring « Extract Microservice » dans IntelliJ. Et bien que l’exemple suivant soit très simplifié, les implémentations observées dans des projets réels ne s’en éloignent malheureusement pas trop. Avant les microservices
@Service
class UserService {
public void register(User user) {
String email = user.getEmail();
String username = email.substring(0, email.indexOf("@"));
// ...
}
}
Avec microservice Java de sous-chaîne
@Service
class UserService {
@Autowired
private HttpClient client;
public void register(User user) {
String email = user.getEmail();
//теперь вызываем substring microservice via http
String username = httpClient.send(substringRequest(email), responseHandler());
// ...
}
}
Vous enveloppez donc essentiellement un appel de méthode Java dans un appel HTTP, sans raison évidente. Cependant, l'une des raisons est la suivante : le manque d'expérience et la tentative d'imposer une approche de microservices Java. Recommandation : ne faites pas cela.
Architecture de microservices orientée workflow
La prochaine approche courante consiste à diviser les microservices Java en modules basés sur des workflows. Exemple concret : en Allemagne, lorsque vous vous rendez chez un médecin (public), celui-ci doit enregistrer votre visite dans son système CRM médical. Pour obtenir le paiement de l'assurance, il enverra des données sur votre traitement (et celui des autres patients) à l'intermédiaire via XML. Le courtier examinera ce fichier XML et (simplifié) :- Vérifie si le fichier XML correct est reçu.
- Il vérifiera la plausibilité des procédures : par exemple, un enfant d'un an qui a subi trois nettoyages de dents en une journée par un gynécologue semble quelque peu suspect.
- Combinera XML avec d'autres données bureaucratiques.
- Enverra le fichier XML à la compagnie d'assurance pour initier les paiements.
- Et il transmettra le résultat au médecin, en lui fournissant le message « succès » ou « veuillez renvoyer cet enregistrement dès que cela aura du sens ».
- Est-il nécessaire de déployer six applications pour traiter un fichier XML ?
- Ces microservices sont-ils vraiment indépendants les uns des autres ? Peuvent-ils être déployés indépendamment les uns des autres ? Avec différentes versions et schémas d'API ?
- Que fait le microservice de plausibilité des informations si le microservice de vérification ne fonctionne pas ? Le système fonctionne-t-il toujours ?
- Ces microservices partagent-ils la même base de données (ils ont certainement besoin de données communes dans les tables de la base de données), ou ont-ils chacun les leurs ?
- … et beaucoup plus.
- Vous n'avez pas besoin de déployer une seule application, mais au moins six.
- Vous devrez peut-être même déployer plusieurs bases de données, en fonction du degré auquel vous souhaitez aller dans l'architecture des microservices.
- Vous devez vous assurer que chaque système est en ligne et fonctionne correctement.
- Vous devez vous assurer que vos appels entre microservices sont réellement résilients (voir Comment rendre un microservice Java résilient ?).
- Et tout ce que cette configuration implique : des paramètres de développement local aux tests d’intégration.
- Si vous n'êtes pas Netflix (il y a de fortes chances que vous n'êtes pas Netflix)...
- À moins que vous n'ayez de très bonnes compétences professionnelles dans lesquelles vous ouvrez l'environnement de développement et cela provoque un singe du chaos qui jette votre base de données de production qui est facilement restaurée en 5 secondes.
- ou vous vous sentez comme @monzo et êtes prêt à essayer 1 500 microservices simplement parce que vous le pouvez.
GO TO FULL VERSION