Spring Cloud a pour objectif de fournir les serveurs et libraires prêts à l'emploi pour permettre les mécanismes suivants dans un cloud de serveurs :
- Configuration distribuée et versionnée
- Enregistrement et de découverte de services
- Routing
- Appels entre services
- Load balancing
- Coupe circuits
- Vérouillage global
- Election d'un leader
- Etat d'un cluster
- Distribution de messages entre services
Spring Cloud se décompose en plusieurs modules:
Pour faciliter la mise en place des serveurs et applications du cloud, il est préférable d'utiliser Spring Boot car il s'intègre très facilement à Spring Cloud via une simple dépendance Maven:
Spring Boot permet la mise en place rapide de serveurs et de services car il s'appuie sur le concept suivant :
- Spring Cloud Netflix :
- Serveurs et librairies open source créés et utilisés par Netflix sur son propre cloud :
- Eureka: Registre et découverte des services
- Hystrix: Monitoring et Reprise des erreurs en cas d'échec
- Ribbon: Load-balancer côté client
- Feign: Déclaration de services REST côté client
- Zuul: Proxy pour le routage et le filtrage
- Documentation :
- Spring Cloud Connectors:
- Simplification de l'accès aux services du Cloud depuis les applications
- Support de Cloud Foundry et de Heroku
- Permet le support d'un cloud personnalisé
- Spring Cloud Config:
- Externalisation de la configuration dans un environnement distribué
- Le serveur Spring Cloud Config Server centralise la configuration des applications sur les différents environnement
- Spring Cloud Bus:
- Serveur RabbitMQ : bus de messages basés sur le protocol AMQP pour la communication point-to-point et publish-subscribe
- Spring Cloud Security:
- Single Sign On basé sur OAuth2
Pour faciliter la mise en place des serveurs et applications du cloud, il est préférable d'utiliser Spring Boot car il s'intègre très facilement à Spring Cloud via une simple dépendance Maven:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> </dependency>
Spring Boot permet la mise en place rapide de serveurs et de services car il s'appuie sur le concept suivant :
- Convention over configuration : nous n'avons plus besoin de tout configurer, Spring Boot utilise la configuration standard. Il est alors possible de surcharger la configuration par défaut via un fichier de configuration YAML
Code source de l'exemple
Pour la mise en oeuvre, le code source est disponible sur le repo Github:
Serveur Eureka
Eureka est un serveur de registre et de découverte de services.
Le fichier
pom.xml
contient la dépendance:
La classe principale Application.java
contient les annotations @EnableEurekaServer
et @EnableDiscoveryClient
:
Le fichier de configuration application.yml
contient le paramétrage du serveur et de Eureka :
Démarrer le serveur Eureka à l'aide de : mvn spring-boot:runAller sur la page : http://localhost:8761
Client Eureka
Nous allons tester l'enregistrement de deux applications "front" et "back" auprès du serveur Eureka.Les deux applications contiennent le fichier
pom.xml
suivant (à part l'artifactId qui est différent):
, avec la dépendance vers :
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency>
Les classes principales
Application.java
dispose de l'annotation @EnableEurekaClient
qui indique que les deux applications seront enregistrées sur le serveur Eureka:Pour l'application "front", nous indiquons dans le fichier
application.yml
le nom "front" pour identifier ensuite cette application dans Eureka, ainsi que le port du serveur Tomcat de cette application. De même pour l'application "back", mais avec comme nom "back"des deux applications "front":
et "back":
Démarrer les deux serveurs en lançant pour chacune la commande :
mvn spring-boot:run
Une fois les deux serveurs lancés, dans la log du serveur, nous voyons que les applications s'enregistrent auprès de Eureka:
pour l'application "back" :
DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local - Re-registering apps/BACK DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local: registering service... DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local - registration status: 204 DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local - retransmit instance info with status UP DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local: registering service... DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local - registration status: 204et pour l'application "front" :
DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local - Re-registering apps/FRONT DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local: registering service... DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local - registration status: 204 DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local - retransmit instance info with status UP DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local: registering service... DiscoveryClient_BOOTSTRAP/MacBook-Pro-de-Ludovic.local - registration status: 204
la page du serveur Eureka http://localhost:8761/ affiche le statut de ces deux applications "front" et "back" que nous venons de démarrer:
Demander à Eureka l'URL d'une application
Dans l'application "front", nous allons nous servir du serveur Eureka pour récupérer l'URL de l'application "back" à partir de son identifiant enregistré dans le serveur Eureka.Nous ajoutons le controlleur suivant dans l'application "front": La classe
DiscoverClient
permet de récupérer les informations d'un service à l'aide de la méthode getNextServerFromEureka
et de l'identifiant de ce service, qui dans notre exemple est "BACK" pour l'application "back".
Le controlleur retourne maintenant l'URL de l'application "back" :
http://localhost:8090/
Cependant, il est préférable de ne pas utiliser directement la classe
DiscoverClient
de Netflix mais d'utiliser un wrapper.Par exemple, la classe
RestTemplate
peut utiliser ce mécanisme en interne: on lui indique une liste de noms de serveurs et c'est elle qui demande au serveur Eureka l'adresse physique de l'application ou serveur cible.
Conclusion
Nous n'avons plus à utiliser directement les adresses physiques des applications et des serveurs. Ce sont eux qui s'enregistrent auprès de Eureka. Ensuite le service client demande à Eureka l'adresse physique du service à qui il souhaite s'adresser.Ceci apporte plus de souplesse dans le paramétrage des environnements et des applications.