Spring Cloud - Amorçage

1. Vue d’ensemble

Spring Cloud est un framework permettant de créer des applications cloud robustes. Le cadre facilite le développement d’applications en apportant des solutions à bon nombre des problèmes courants rencontrés lors du passage à un environnement distribué.

Les applications fonctionnant avec une architecture microservices visent à simplifier le développement, le déploiement et la maintenance. La nature décomposée de l’application permet aux développeurs de se concentrer sur un problème à la fois.

Des améliorations peuvent être introduites sans impact sur les autres parties d’un système.

Par ailleurs, l’adoption d’une approche de microservice pose différents défis:

  • Externaliser la configuration de manière flexible et sans nécessiter

reconstruction du service sur le changement ** Découverte de service

  • Masquer la complexité des services déployés sur différents hôtes

Dans cet article, nous allons créer cinq microservices: un serveur de configuration, un serveur de découverte, un serveur de passerelle, un service de livre et enfin un service d’évaluation. Ces cinq microservices forment une application de base solide pour commencer le développement du cloud et relever les défis susmentionnés.

2. Serveur de configuration

Lors du développement d’une application cloud, l’un des problèmes est de maintenir et de distribuer la configuration à nos services. Nous ne voulons vraiment pas perdre de temps à configurer chaque environnement avant de mettre notre service à l’échelle horizontalement ou de risquer des failles de sécurité en intégrant notre configuration dans notre application.

Pour résoudre ce problème, nous allons consolider toute notre configuration dans un seul référentiel Git et le connecter à une application gérant une configuration pour toutes nos applications. Nous allons mettre en place une implémentation très simple.

Pour en savoir plus et voir un exemple plus complexe, consultez l’article de lien:/spring-cloud-configuration[Spring Cloud Configuration].

2.1. Installer

Accédez à start.spring.io et sélectionnez Maven et Spring Boot 1.4.x.

Définissez l’artefact sur « config» . Dans la section des dépendances, recherchez « config server» et ajoutez ce module. Appuyez ensuite sur le bouton generate et vous pourrez télécharger un fichier zip contenant un projet préconfiguré et prêt à fonctionner.

Alternativement, nous pouvons générer un projet Spring Boot et ajouter manuellement des dépendances au fichier POM.

Ces dépendances seront partagées entre tous les projets:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Brixton.SR5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Ajoutons une dépendance pour le serveur de configuration:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

Pour référence: vous pouvez trouver la dernière version sur Maven Central ( https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A% 22spring-cloud-dependencies% 22[printemps-cloud-dependencies], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20and%20and%20a% 3A% 22spring-boot-starter-test% 22[test], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20and%20and%20a% 3A% 22spring-cloud-config-server% 22[config-server]).

2.2. Config de printemps

Pour activer le serveur de configuration, nous devons ajouter des annotations à la classe d’application principale:

@SpringBootApplication
@EnableConfigServer
public class ConfigApplication {...}

@ EnableConfigServer transformera notre application en serveur de configuration.

2.3. Propriétés

Ajoutons le application.properties dans src/main/resources:

server.port=8081
spring.application.name=config

spring.cloud.config.server.git.uri=file://${user.home}/application-config

Le paramètre le plus significatif pour le serveur de configuration est le paramètre git.uri . Ceci est actuellement défini sur un chemin de fichier relatif qui résout généralement en c: \ Users \\ {username} \ sous Windows ou /Users/\ {username}/ sur ** nix. Cette propriété pointe vers un référentiel Git dans lequel les fichiers de propriétés de toutes les autres applications sont stockés. Il peut être défini sur un chemin de fichier absolu si nécessaire.

  • Astuce : Sur une machine Windows, insérez ‘file:///’ dans la valeur, puis nix, utilisez ‘file://’.

2.4. Dépôt Git

Accédez au dossier défini par spring.cloud.config.server.git.uri et ajoutez le dossier ‘application-config’. CD dans ce dossier et tapez git init . Cela initialisera un référentiel Git où nous pourrons stocker des fichiers et suivre leurs modifications.

2.5. Courir

Lançons le serveur de configuration et s’assurent qu’il fonctionne. Dans la ligne de commande, tapez mvn spring-boot: run . Cela va démarrer le serveur. Vous devriez voir cette sortie indiquant que le serveur est en cours d’exécution:

Tomcat started on port(s): 8081 (http)

3. Découverte

Maintenant que nous avons pris en charge la configuration, nous avons besoin d’un moyen pour que tous nos serveurs puissent se retrouver. Nous allons résoudre ce problème en configurant le serveur de découverte Eureka . Étant donné que nos applications peuvent fonctionner sur n’importe quelle combinaison ip/port, nous avons besoin d’un registre d’adresses central pouvant servir de recherche d’adresse.

Lorsqu’un nouveau serveur est mis en service, il communique avec le serveur de découverte et enregistre son adresse afin que d’autres puissent communiquer avec lui.

De cette façon, d’autres applications peuvent utiliser ces informations lorsqu’elles font des demandes.

Pour en savoir plus et voir une implémentation de découverte plus complexe, consultez le lien:/spring-cloud-netflix-eureka[article de Spring Cloud Eureka].

3.1. Installer

De nouveau, nous allons naviguer vers start.spring.io . Définissez l’artefact sur "découverte". Recherchez «serveur eureka» et ajoutez cette dépendance. Recherchez « config client » et ajoutez cette dépendance.

Générez le projet.

Alternativement, nous pouvons créer un projet Spring Boot , copier le contenu du POM à partir du serveur de configuration et permuter dans les dépendances suivantes:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

Pour référence: vous trouverez les ensembles sur Maven Central ( https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20and%20a%3a%3a%22spring -cloud-starter-config% 22[client-config], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20and%20a%3A % 22spring-cloud-starter-eureka-server% 22[eureka-server]).

3.2. Config de printemps

Ajoutons la configuration Java à la classe principale:

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryApplication {...}

@ EnableEurekaServer configurera ce serveur en tant que serveur de découverte utilisant Netflix Eureka . Spring Boot détectera automatiquement la dépendance de la configuration sur le chemin de classe et recherchera la configuration à partir du serveur de configuration.

3.3. Propriétés

Nous allons maintenant ajouter deux fichiers de propriétés:

bootstrap.properties dans src/main/resources

spring.cloud.config.name=discovery
spring.cloud.config.uri=http://localhost:8081

Ces propriétés laisseront le serveur de découverte interroger le serveur de configuration au démarrage.

discovery.properties dans notre référentiel Git

spring.application.name=discovery
server.port=8082

eureka.instance.hostname=localhost

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

Le nom de fichier doit correspondre à la propriété spring.application.name .

De plus, nous disons à ce serveur qu’il fonctionne dans la zone par défaut, cela correspond au paramètre de région du client de configuration. Nous demandons également au serveur de ne pas s’inscrire auprès d’une autre instance de découverte.

En production, vous auriez plus d’un de ceux-ci pour assurer la redondance en cas d’échec et ce paramètre serait vrai.

Commençons le fichier dans le référentiel Git. Sinon, le fichier ne sera pas détecté.

3.4. Ajouter une dépendance au serveur de configuration

Ajoutez cette dépendance au fichier POM du serveur de configuration:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

Pour référence : vous trouverez le package sur Maven Central ( https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20and%20a % 3A% 22spring-cloud-starter-eureka% 22[client eureka]).

Ajoutez ces propriétés au fichier application.properties dans src/main/resources du serveur de configuration:

eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5
eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

====  **  3.5. Courir**

Démarrez le serveur de découverte en utilisant la même commande, __mvn spring-boot: run__. La sortie de la ligne de commande devrait inclure:

[source,text,gutter:,true]

Fetching config from server at: http://localhost:8081 …​ Tomcat started on port(s): 8082 (http)

Arrêtez et réexécutez le service de configuration. Si tout est bon, le résultat devrait ressembler à ceci:

[source,text,gutter:,true]

DiscoveryClient CONFIG/10.1.10.235:config:8081: registering service…​ Tomcat started on port(s): 8081 (http) DiscoveryClient CONFIG/10.1.10.235:config:8081 - registration status: 204

===  **  4. Passerelle**

Maintenant que nos problèmes de configuration et de découverte sont résolus, nous avons toujours un problème avec les clients accédant à toutes nos applications.

Si nous laissons tout dans un système distribué, nous devrons alors gérer des en-têtes CORS complexes pour autoriser les demandes d'origine croisée sur les clients.

Nous pouvons résoudre ce problème en créant un serveur __Gateway__. Cela agira comme une requête de transfert de proxy inverse des demandes des clients vers nos serveurs principaux.

Un serveur de passerelle est une excellente application dans l'architecture de microservices, car il permet à toutes les réponses de provenir d'un seul hôte.

Cela éliminera le besoin de CORS et nous donnera un endroit pratique pour traiter les problèmes courants tels que l'authentification.

====  **  4.1. Installer**

Nous connaissons maintenant l'exercice. Accédez à http://start.spring.io/[start.spring.io]. Définissez l’artefact sur «__gateway__». Recherchez «zuul» et ajoutez cette dépendance. Recherchez «client __config» __ et ajoutez cette dépendance. Recherchez “__eureka discovery” __ et ajoutez cette dépendance. Générez ce projet.

Alternativement, nous pourrions créer une application __Spring Boot__ avec ces dépendances:

[source,xml,gutter:,true]

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency>

Pour référence: vous trouverez le kit sur __Maven Central__ (https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20and%20a%3a%3a%22spring -cloud-starter-config% 22[client-config], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20and%20a%3A % 22spring-cloud-starter-eureka% 22[client eureka], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20%20and%20a % 3A% 22spring-cloud-starter-zuul% 22[zuul]).

====  **  4.2. Config de printemps **

Ajoutons la configuration à la classe principale:

[source,java,gutter:,true]

@SpringBootApplication @EnableZuulProxy @EnableEurekaClient public class GatewayApplication {…​}

====  **  4.3. Propriétés**

Nous allons maintenant ajouter deux fichiers de propriétés:

__bootstrap.properties__ dans src/main/resources

[source,text,gutter:,true]

spring.cloud.config.name=gateway spring.cloud.config.discovery.service-id=config spring.cloud.config.discovery.enabled=true

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

gateway.properties dans notre référentiel Git

spring.application.name=gateway
server.port=8080

eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5

zuul.routes.book-service.path=/book-service/** **
zuul.routes.book-service.sensitive-headers=Set-Cookie,Authorization
hystrix.command.book-service.execution.isolation.thread.timeoutInMilliseconds=600000

zuul.routes.rating-service.path=/rating-service/** **
zuul.routes.rating-service.sensitive-headers=Set-Cookie,Authorization
hystrix.command.rating-service.execution.isolation.thread.timeoutInMilliseconds=600000

zuul.routes.discovery.path=/discovery/** **
zuul.routes.discovery.sensitive-headers=Set-Cookie,Authorization
zuul.routes.discovery.url=http://localhost:8082
hystrix.command.discovery.execution.isolation.thread.timeoutInMilliseconds=600000

La propriété zuul.routes nous permet de définir une application pour router certaines demandes en fonction d’un matcher URL ant. Notre propriété indique à Zuul de router toute demande provenant de "/book-service/ " vers une application avec le spring.application.name de "book-service". Zuul recherchera ensuite l’hôte auprès du serveur de découverte à l’aide du nom de l’application et transférera la demande à ce serveur.

N’oubliez pas de valider les modifications dans le référentiel!

4.4. Courir

Exécutez les applications de configuration et de découverte et attendez que l’application de configuration se soit inscrite auprès du serveur de reconnaissance. S’ils sont déjà en cours d’exécution, vous ne devez pas les redémarrer. Une fois cette opération terminée, exécutez le serveur de passerelle. Le serveur de passerelle doit démarrer sur le port 8080 et s’enregistrer auprès du serveur de découverte. La sortie de la console devrait contenir:

Fetching config from server at: http://10.1.10.235:8081/...
DiscoveryClient__GATEWAY/10.1.10.235:gateway:8080: registering service...
DiscoveryClient__GATEWAY/10.1.10.235:gateway:8080 - registration status: 204
Tomcat started on port(s): 8080 (http)

Une erreur facile à commettre est de démarrer le serveur avant que le serveur de configuration se soit enregistré avec Eureka . Dans ce cas, vous verrez un journal avec cette sortie:

Fetching config from server at: http://localhost:8888

Il s’agit de l’URL et du port par défaut d’un serveur de configuration. Ils indiquent que notre service de découverte n’avait pas d’adresse au moment de la demande de configuration. Attendez quelques secondes et réessayez. Une fois le serveur de configuration enregistré auprès d’Eureka, le problème sera résolu.

5. Service de réservation

Dans l’architecture de microservice, nous sommes libres de créer autant d’applications que possible pour atteindre un objectif commercial. Les ingénieurs divisent souvent leurs services par domaine. Nous allons suivre ce modèle et créer un service de livre pour gérer toutes les opérations pour les livres dans notre application.

5.1. Installer

Encore une fois. Accédez à start.spring.io . Définissez l’artefact sur "book-service". Recherchez « web » et ajoutez cette dépendance. Recherchez « config client » et ajoutez cette dépendance. Recherchez «Eureka discovery» et ajoutez cette dépendance. Générez ce projet.

Vous pouvez également ajouter ces dépendances à un projet:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

5.2. Config de printemps

Modifions notre classe principale:

@SpringBootApplication
@EnableEurekaClient
@RestController
@RequestMapping("/books")
public class BookServiceApplication {
    public static void main(String[]args) {
        SpringApplication.run(BookServiceApplication.class, args);
    }

    private List<Book> bookList = Arrays.asList(
        new Book(1L, "Baeldung goes to the market", "Tim Schimandle"),
        new Book(2L, "Baeldung goes to the park", "Slavisa")
    );

    @GetMapping("")
    public List<Book> findAllBooks() {
        return bookList;
    }

    @GetMapping("/{bookId}")
    public Book findBook(@PathVariable Long bookId) {
        return bookList.stream().filter(b -> b.getId().equals(bookId)).findFirst().orElse(null);
    }
}

Nous avons également ajouté un contrôleur REST et un champ défini par notre fichier de propriétés pour renvoyer une valeur que nous définirons lors de la configuration.

Ajoutons maintenant le livre POJO:

public class Book {
    private Long id;
    private String author;
    private String title;

   //standard getters and setters
}

5.3. Propriétés

Il ne reste plus qu’à ajouter nos deux fichiers de propriétés:

bootstrap.properties dans src/main/resources:

spring.cloud.config.name=book-service
spring.cloud.config.discovery.service-id=config
spring.cloud.config.discovery.enabled=true

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

book-service.properties dans votre référentiel Git:

[source,text,gutter:,true]

spring.application.name=book-service server.port=8083

eureka.client.region = default eureka.client.registryFetchIntervalSeconds = 5 eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

Commettons les modifications dans le référentiel.

5.4. Courir

Une fois que toutes les autres applications ont démarré, nous pouvons démarrer le service de livre. La sortie de la console devrait ressembler à:

DiscoveryClient__BOOK-SERVICE/10.1.10.235:book-service:8083: registering service...
DiscoveryClient__BOOK-SERVICE/10.1.10.235:book-service:8083 - registration status: 204
Tomcat started on port(s): 8083 (http)

Une fois que c’est terminé, nous pouvons utiliser notre navigateur pour accéder au terminal que nous venons de créer. Accédez à http://localhost : 8080/book-service/books et nous récupérons un objet JSON avec deux livres ajoutés au contrôleur out. Notez que nous n’accédons pas directement au service de réservation sur le port 8083, mais que nous passons par le serveur de passerelle.

6. Service d’évaluation

À l’instar de notre service de publication, notre service d’évaluation sera un service axé sur le domaine qui gérera les opérations liées aux évaluations.

6.1. Installer

Encore une fois. Accédez à start.spring.io . Définissez l’artefact sur ‘rating-service’. Recherchez « web » et ajoutez cette dépendance. Recherchez « config client » et ajoutez cette dépendance. Recherchez «Eureka discovery» et ajoutez cette dépendance. Générez ce projet.

Vous pouvez également ajouter ces dépendances à un projet:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

6.2. Config de printemps

Modifions notre classe principale:

@SpringBootApplication
@EnableEurekaClient
@RestController
@RequestMapping("/ratings")
public class RatingServiceApplication {
    public static void main(String[]args) {
        SpringApplication.run(RatingServiceApplication.class, args);
    }

    private List<Rating> ratingList = Arrays.asList(
        new Rating(1L, 1L, 2),
        new Rating(2L, 1L, 3),
        new Rating(3L, 2L, 4),
        new Rating(4L, 2L, 5)
    );

    @GetMapping("")
    public List<Rating> findRatingsByBookId(@RequestParam Long bookId) {
        return bookId == null || bookId.equals(0L) ? Collections.EMPTY__LIST : ratingList.stream().filter(r -> r.getBookId().equals(bookId)).collect(Collectors.toList());
    }

    @GetMapping("/all")
    public List<Rating> findAllRatings() {
        return ratingList;
    }
}

Nous avons également ajouté un contrôleur REST et un champ défini par notre fichier de propriétés pour renvoyer une valeur que nous définirons lors de la configuration.

Ajoutons la note POJO:

public class Rating {
    private Long id;
    private Long bookId;
    private int stars;

   //standard getters and setters
}

6.3. Propriétés

Il ne reste plus qu’à ajouter nos deux fichiers de propriétés:

bootstrap.properties dans src/main/resources:

spring.cloud.config.name=rating-service
spring.cloud.config.discovery.service-id=config
spring.cloud.config.discovery.enabled=true

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

__rating-service.properties__ dans notre référentiel Git:

[source,text,gutter:,true]

spring.application.name=rating-service server.port=8084

eureka.client.region = default eureka.client.registryFetchIntervalSeconds = 5 eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

Commettons les modifications dans le référentiel.

6.4. Courir

Une fois que toutes les autres applications ont démarré, nous pouvons démarrer le service d’évaluation. La sortie de la console devrait ressembler à:

DiscoveryClient__RATING-SERVICE/10.1.10.235:rating-service:8083: registering service...
DiscoveryClient__RATING-SERVICE/10.1.10.235:rating-service:8083 - registration status: 204
Tomcat started on port(s): 8084 (http)

Une fois que c’est terminé, nous pouvons utiliser notre navigateur pour accéder au terminal que nous venons de créer. Accédez à http://localhost : 8080/rating-service/ratings/all et nous recevrons JSON contenant toutes nos évaluations. Notez que nous n’accédons pas directement au service d’évaluation sur le port 8084, mais que nous passons par le serveur de passerelle.

7. Conclusion

Nous sommes maintenant en mesure de connecter les différentes parties de Spring Cloud dans une application de microservice fonctionnelle. Ceci constitue une base utilisable pour commencer à créer des applications plus complexes.

Comme toujours, vous pouvez trouver ce code source sur Github .