Il y a 4 ans -
Temps de lecture 9 minutes
Patterns de microservices avec Spring Cloud (1/2)
Introduction
Il y a une dizaine d’années, la plupart des applications Web étaient construites selon un style architectural monolithique. Mais la plupart du temps, plusieurs équipes de développement travaillent sur l’application. Chaque équipe de développement a ses propres composants de l’application dont elle est responsable. Avec le temps, l’application grossit et il faut découper le monolithe pour pouvoir développer l’application en parallèle et pouvoir la déployer indépendamment. Le concept de microservices est une réponse directe au défi de la mise à l’échelle d’applications monolithiques.
Parallèlement, Spring, avec en particulier Spring Boot, est devenu le choix par défaut pour la création d’applications développées en Java. Les microservices étant devenus l’un des modèles d’architecture les plus courants pour la création d’applications basées sur le cloud, la communauté de développement Spring nous a fourni Spring Cloud parce que Spring Boot n’implémente pas les patterns spécifiques aux architectures microservice qui vont être présentés. Dans cette série d’articles, nous passerons en revue plusieurs des patterns proposés par Spring Cloud :
- Gestion de la configuration
- Découverte de services
- Passerelle de service
- Circuit breaker, Fallback processing, Bulkhead
Un premier article présentera la gestion de la configuration, avec Spring Config, et la découverte de services, avec Eureka. Il sera suivi d’un second article, qui abordera les passerelles de services avec Zuul et les notions de circuit breakers, de fallback processing et de bulkhead avec Hystrix.
Gestion de configuration – Spring Cloud Config
Introduction du problème
Les données de configuration d’application écrites directement dans le code sont souvent problématiques, car chaque fois qu’une modification de la configuration doit être effectuée, l’application doit être recompilée et / ou redéployée. Pour éviter cela, il est recommandé aux développeurs de séparer complètement les informations de configuration du code de l’application (le troisième facteur de la méthodologie Twelve-Factor App).
Il est possible d’utiliser un fichier de propriétés (YAML, JSON, XML, etc.) pour stocker leurs informations de configuration.
Cette approche peut s’appliquer à un petit nombre d’applications, mais elle devient rapidement trop lourde lorsqu’il s’agit d’applications distribuées pouvant contenir des centaines de microservices.
Pour résoudre ce problème, nous allons utiliser Spring Cloud Config qui implémente le pattern Gestion de configuration.
Diagramme du pattern
Le diagramme ci-dessous présente la récupération de la configuration par les instances de microservices lors de leur démarrage.
Spring Cloud Config gère les données de configuration des applications via un service centralisé, de sorte que les données de configuration de vos applications (en particulier celles de votre environnement) soient clairement séparées de votre microservice déployé. Cela garantit que, peu importe le nombre d’instances de microservices que vous avez lancées, elles auront toujours la même configuration. Spring Cloud Config possède son propre dépôt de gestion de propriétés, mais s’intègre également à des projets open source tels que Git, Consul et Eureka. Nous allons utiliser Git dans cet article.
-
la séparation de la configuration d’une application du code
- la construction du serveur et de l’application : les livrables ne seront plus recompilés, mais promus d’un environnement à un autre
-
l’injection d’informations de configuration d’application au démarrage du serveur par le biais de variables d’environnement ou d’un dépôt centralisé
Configuration de Spring Cloud Config
<!-- Les dépendances de Spring Cloud Config --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency>
[xml]# Spring Cloud Config application.yml
server:
port: 8888 # le port de Spring Cloud Config
spring:
cloud:
config:
server:
git:
uri: file:///Users/oslynko/IdeaProjects/springmicroservices/config-repo/ # uri du dépôt Git qui contient la configuration[/xml]
[java]@SpringBootApplication
@EnableConfigServer // l’annotation qui permet la gestion de la configuration
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
[/java]
Exemple de Postman
Nous allons utiliser les profils Spring pour les tests Postman. Il y a 2 fichiers dans le dépot:
message-service.yml
message-service-dev.yml
La convention de nommage des fichiers est {application}-{profile}.yml
Nous allons utiliser Postman pour récupérer les propriétés de configuration avec le profil par défaut, puis avec le profil dev.
En cas d’appel à http://localhost:8888/message-service/default, Spring Cloud Config prend les propriétés du fichier message-service.yml
qui se trouve dans le dépôt
En cas d’appel à http://localhost:8888/message-service/dev, Spring Cloud Config prend les propriétés du fichier message-service-dev.yml
qui se trouve dans le dépôt
Exemple d’interaction
Pour tester l’intégration, nous allons créer un microservice d’exemple (le service « Message ») qui va récupérer ses propriétés depuis Config Server.
[xml]# Message service application.yml
server:
port: 8080 # le port du microservice d’exemple (Message service)
spring:
application:
name: message-service # le nom du service, le nom est utilisé pour identification
cloud:
config:
uri: http://localhost:8888 # Spring Cloud Config uri, toutes les propriétés viennent de ce service[/xml]
[xml]# Message service bootstrap.properties
spring.profiles.active=dev[/xml]
En cas d’appel à http://localhost:8080/message, Message service prend les propriétés de Spring Cloud Config qui prend les propriétés du fichier message-service-dev.yml
Conclusion
-
Spring Cloud Config vous permet de configurer les propriétés de l’application avec des valeurs spécifiques à l’environnement
-
Spring utilise des
profils Spring pour lancer un service afin de déterminer les propriétés d’environnement à extraire du service Spring Cloud Config -
Spring Cloud Config peut utiliser un dépôt de configuration d’application basé sur un fichier ou sur Git pour stocker les propriétés de l’application
Découverte de services – Spring Cloud / Netflix Eureka
Introduction du problème
Si une équipe gère des serveurs physiques, un fichier de configuration répond essentiellement au besoin de découverte de services, ce fichier permet de savoir quelle adresse utiliser pour appeler un service.
Mais vos services peuvent avoir un emplacement réseau dynamique en raison d’un redémarrage, d’une défaillance et d’une mise à l’échelle. Maintenir manuellement un fichier de configuration n’est tout simplement pas faisable.
Pour résoudre ce problème, nous allons utiliser Eureka qui implémente le pattern Découverte de services.
Diagramme du pattern
Description du pattern
- La découverte de services est essentielle pour les microservices pour deux raisons principales. Elle offre à l’application la possibilité d’augmenter rapidement le nombre d’instances de service exécutés
dans un environnement. Les consommateurs de services sont abstraits de l’emplacement physique du service via la découverte de services. Étant donné que les consommateurs de services ne connaissent pas l’emplacement physique des instances de service réelles, de nouvelles instances de service peuvent être ajoutées ou supprimées du pool de services disponibles. -
Cette capacité à adapter rapidement les services sans perturber les utilisateurs de services permet à une équipe de développement habituée à la création d’applications monolithiques d’adopter l’approche la plus puissante pour la mise à l’échelle en ajoutant davantage de serveurs.
-
Le deuxième avantage de la découverte de services est qu’elle contribue à augmenter la résilience des applications. Lorsqu’une instance de microservice devient instable ou indisponible, la plupart des moteurs de découverte de services la suppriment de la liste interne des services disponibles. Les dommages causés par un service indisponible seront minimisés car le moteur de découverte de services acheminera les appels aux services disponibles.
Configuration de Eureka
<!-- Les dépendances de Eureka client (message service) --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
[xml]# Eureka application.yml
server:
port: 8761
eureka:
client:
registerWithEureka: false # Ne pas s’enregistrer auprès du service Eureka.
fetchRegistry: false # Ne cache pas les informations de registre localement.
server:
waitTimeInMsWhenSyncEmpty: 5 # Temps initial d’attente avant que le serveur accepte les demandes[/xml]
[java]@SpringBootApplication
@EnableEurekaServer // l’annotation qui permet la découverte de services
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}[/java]
Configuration de Eureka client
<!-- Les dépendances de Eureka client (message service) --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
[xml]# Eureka client (message service) application.yml
server:
port: 8080
spring:
application:
name: message-service # le nom du service, le nom est utilisé pour identification du service
eureka:
instance:
preferIpAddress: true
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/ # url de Eureka Server[/xml]
Exemple d’interaction
Nous avons configuré le serveur Eureka et le service Message. Nous allons maintenant les démarrer. Dans les logs du service Message, nous voyons les détails de l’enregistrement du service.
Dans les logs on peut voir que Message service enregistre l’adresse IP sur le serveur Eureka lors du démarrage.
En cas d’appel à http://localhost:8761, on voit que Message service a été enregistré auprès d’Eureka.
Pour tester l’intégration avec Eureka, nous utiliserons OpenFeign Declarative REST Client : OpenFeign crée une implémentation dynamique d’une interface décorée avec des annotations JAX-RS ou Spring MVC.
-
Eureka est utilisé pour abstraire la localisation physique des services.
-
Un moteur de découverte de services tel qu’Eureka peut ajouter et supprimer de manière transparente des instances de service d’un environnement sans que les clients du service ne soient affectés.
-
Eureka est un projet Netflix qui, lorsqu’il est utilisé avec Spring Cloud, est facile à configurer.
Pour aller plus loin, le code source du projet utilisé comme exemple est disponible sur Github : https://github.com/slynko/springmicroservices
Commentaire
3 réponses pour " Patterns de microservices avec Spring Cloud (1/2) "
Published by Angelov , Il y a 4 ans
Super intéressant et enrichissant pour les débutants en Spring, à quand le volet ?
Published by Oleksandr Slynko , Il y a 4 ans
Merci, la partie 2 est déjà en cours.
Published by jle , Il y a 3 ans
Salut,
Sympa !
néanmoins, sur la première partie (config via un repo git), je pense que l’on pourrait s’attendre à un autre fonctionnement :
– tu tapes sur http://localhost:8888/message-service/ (pas de /default ni /dev) et ce endpoint retourne un message différent selon le profil avec lequel l’appli a été lancée (donc bootstrap.yml à retirer, et passer le profil en param d’appli/env)
– montrer comment on stocke la configuration sur le repo git. Par quels fichiers se traduisent les profils ? Est-ce qu’on dépose juste des yml ? Avec quels noms ?
Merci,