|
| 1 | +# Starter Microservices Spring Cloud |
| 2 | + |
| 3 | +Dans cet article, je vous présente mon projet de starter microservices basé sur l’écosystème **Spring Cloud**, incluant **Eureka**, **Cloud Config**, **Gateway**, **Axon**, **RabbitMQ**, et **PostgreSQL**. L’objectif est de fournir un exemple de configuration et d’implémentation entièrement réactive et scalable. |
| 4 | +Dans un environnement 100% réactif avec **WebFlux** et **R2DBC**(Non bloquant), les microservices communiquent entre eux de manière asynchrone, |
| 5 | +ce qui permet de gérer un grand nombre de requêtes simultanées. |
| 6 | + |
| 7 | +Le project est modulaire et évolutif disponible dans ici : |
| 8 | +[https://github.com/coundia/spring-microservices-starter](https://github.com/coundia/spring-microservices-starter) |
| 9 | + |
| 10 | +## Sommaire |
| 11 | +1. [Architecture Globale](#architecture-globale) |
| 12 | +2. [Services Principaux](#services-principaux) |
| 13 | +3. [Configuration Eureka](#configuration-eureka) |
| 14 | +4. [Configuration du Cloud Config Server](#configuration-du-cloud-config-server) |
| 15 | +5. [Configuration du Gateway](#configuration-du-gateway) |
| 16 | +6. [Axon, RabbitMQ, et PostgreSQL](#axon-rabbitmq-et-postgresql) |
| 17 | +7. [Sécuriser les Microservices](#securiser-les-microservices) |
| 18 | +8. [Conclusion](#conclusion) |
| 19 | + |
| 20 | +--- |
| 21 | + |
| 22 | +## Architecture Globale |
| 23 | + |
| 24 | +Voici un aperçu de la structure du projet : |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +- **Cloud Config Server (Port 8081)** : Serveur de configuration centralisé. |
| 29 | +- **Eureka (Port 8761)** : Service de découverte pour enregistrer et localiser les microservices. |
| 30 | +- **Gateway (Port 8080)** : Point d’entrée unique, qui fait du load-balancing et du routage. |
| 31 | +- **Product-Command (Port 8090)** : Microservice pour gérer les commandes (CUD) des produits. |
| 32 | +- **Product-Query (Port 8091)** : Microservice pour gérer la consultation (Read) des produits. |
| 33 | + |
| 34 | +L’ensemble est orchestré par Docker ou Docker Compose pour une gestion simplifiée de l’infrastructure. |
| 35 | +## Architecture DDD |
| 36 | + |
| 37 | +Le projet est basé sur l'architecture **DDD** (Domain Driven Design) avec les couches suivantes : |
| 38 | + |
| 39 | + |
| 40 | + |
| 41 | +source: https://www.hibit.dev/posts/15/domain-driven-design-layers |
| 42 | + |
| 43 | +- **Domain Layer** : Contient les entités, les valeurs d’objet, les agrégats, les événements, les commandes, les gestionnaires de commandes, les spécifications, les services de domaine, etc. |
| 44 | +- **Application Layer** : Contient les services d’application, les gestionnaires de commandes, les gestionnaires de requêtes, les gestionnaires d’événements, etc. |
| 45 | +- **Infrastructure Layer** : Contient les implémentations des interfaces de persistance, les implémentations des interfaces de messagerie, les implémentations des interfaces de configuration, etc. |
| 46 | +- **Presentation Layer** : Contient les contrôleurs REST (@RestController) |
| 47 | + |
| 48 | +## Services Principaux |
| 49 | + |
| 50 | +### Cloud Config Server |
| 51 | +Ce service charge la configuration depuis un dépôt Git local ou distant. L’application consomme ensuite cette configuration au démarrage pour centraliser et uniformiser la configuration. |
| 52 | + |
| 53 | +### Eureka |
| 54 | +Chaque service s’enregistre auprès de **Eureka** et peut ensuite découvrir les autres services par leur nom logique, sans avoir à connaître les adresses réseau exactes. |
| 55 | + |
| 56 | +### Gateway |
| 57 | +Permet de centraliser toutes les requêtes sortantes et entrantes. |
| 58 | +Les clients externes n’ont accès qu’au Gateway, qui fait office de passerelle. |
| 59 | +Il gère également la résilience avec **Resilience4j** |
| 60 | + |
| 61 | +### Product-Command |
| 62 | +C’est le microservice pour les opérations d’écriture (Create, Update, Delete) sur les produits. Il peut utiliser **Axon** et **RabbitMQ** pour émettre des événements. |
| 63 | + |
| 64 | +### Product-Query |
| 65 | +Ce microservice expose des requêtes en lecture pour récupérer la liste ou le détail des produits. |
| 66 | + |
| 67 | +## Configuration Eureka |
| 68 | + |
| 69 | +Voici un extrait typique du `application.properties` pour Eureka : |
| 70 | + |
| 71 | +```properties |
| 72 | +spring.application.name=eureka |
| 73 | +server.port=8761 |
| 74 | + |
| 75 | +# Désactive la découverte pour lui-même |
| 76 | +eureka.client.register-with-eureka=false |
| 77 | + |
| 78 | +# eureka.client.fetch-registry=false car c’est le serveur |
| 79 | +management.endpoints.web.exposure.include=health,info |
| 80 | +``` |
| 81 | + |
| 82 | +Une fois démarré, Eureka sera accessible sur `http://localhost:8761/`. |
| 83 | + |
| 84 | +## Configuration du Cloud Config Server |
| 85 | + |
| 86 | +Exemple de configuration minimale : |
| 87 | + |
| 88 | +```properties |
| 89 | +spring.application.name=cloud-config-server |
| 90 | +server.port=8081 |
| 91 | +spring.cloud.config.server.git.uri=/MON-PATH/config-repo |
| 92 | +``` |
| 93 | + |
| 94 | +Dans le dépôt local `config-repo/`, on placera les fichiers `gateway-server.properties`, `product-command.properties`, etc., pour centraliser la configuration. |
| 95 | + |
| 96 | +## Configuration du Gateway |
| 97 | + |
| 98 | +Le Gateway utilise les routes pour rediriger les requêtes vers les microservices : |
| 99 | + |
| 100 | +```properties |
| 101 | +spring.application.name=gateway-server |
| 102 | +server.port=8080 |
| 103 | +eureka.client.serviceUrl.defaultZone=http://192.168.1.23:8761/eureka/ |
| 104 | + |
| 105 | +spring.cloud.gateway.discovery.locator.enabled=true |
| 106 | +spring.cloud.gateway.discovery.locator.lower-case-service-id=true |
| 107 | + |
| 108 | +spring.cloud.gateway.routes[0].id=product-command-route |
| 109 | +spring.cloud.gateway.routes[0].uri=lb://PRODUCT-COMMAND |
| 110 | +spring.cloud.gateway.routes[0].predicates[0]=Path=/api/v1/commands/products/** |
| 111 | +``` |
| 112 | + |
| 113 | +## Axon, RabbitMQ et PostgreSQL |
| 114 | + |
| 115 | +- **Axon** : Framework de mise en œuvre de **CQRS** et **Event Sourcing**. |
| 116 | +- **RabbitMQ** : Broker de messages pour la communication asynchrone. |
| 117 | +- **PostgreSQL** : Base de données relationnelle pour persister les données (Il sert egalement de event store). |
| 118 | + |
| 119 | +### Exemple de test réactif |
| 120 | + |
| 121 | +```java |
| 122 | +@Test |
| 123 | +void it_should_create_aggregate_reactively() { |
| 124 | + Mono<String> result = Mono.fromFuture( |
| 125 | + commandGateway.send(new CreateProductCommand("productId", "productName")) |
| 126 | + ); |
| 127 | + StepVerifier.create(result) |
| 128 | + .expectNext("productId") |
| 129 | + .verifyComplete(); |
| 130 | +} |
| 131 | +``` |
| 132 | + |
| 133 | +## Sécuriser les Microservices |
| 134 | + |
| 135 | +Pour vous assurer que seuls les appels venant du Gateway sont autorisés, vous pouvez ajouter un header spécifique (ex. `X-Gateway-Auth`) via un **Route Filter** ou un **Global Filter** dans Gateway, et vérifier la présence de ce header côté microservices : |
| 136 | + |
| 137 | +```properties |
| 138 | +spring.cloud.gateway.routes[0].filters[0]=AddRequestHeader=X-Gateway-Auth,true |
| 139 | +``` |
| 140 | + |
| 141 | +Ensuite, dans chaque microservice : |
| 142 | + |
| 143 | +```java |
| 144 | +.http.authorizeExchange(exchanges -> exchanges |
| 145 | + .pathMatchers("/api/v1/commands/**").access(gatewayAuthManager) |
| 146 | + .anyExchange().permitAll() |
| 147 | +) |
| 148 | +``` |
| 149 | + |
| 150 | +## Conclusion |
| 151 | + |
| 152 | +Ce starter fournit une architecture solide basée sur **Spring Cloud**, **Axon**, **RabbitMQ**, et **PostgreSQL**. |
| 153 | +L’objectif est de montrer comment mettre en place une infrastructure microservices réactive, scalable et maintenable. Vous pouvez cloner ce projet, personnaliser la configuration, et ajouter vos propres fonctionnalités pour répondre à vos besoins métiers. |
| 154 | + |
0 commit comments