Aller au contenu principal

Quiz: Spring Cloud et Microservices

Testez vos connaissances sur l'architecture microservices et Spring Cloud.

30 questions - Cliquez sur chaque question pour révéler la réponse.


Questions 1-10: Architecture Microservices​

Question 1: Quelle est la différence entre monolithe et microservices?

Réponse:

MonolitheMicroservices
Une seule applicationServices indépendants
Une base de donnéesDB par service
Déploiement globalDéploiement indépendant
Scaling globalScaling par service
Simple au débutComplexe au début
Couplage fortCouplage faible

Question 2: Quand choisir une architecture microservices?

Réponse:

  • Grande équipe (multiples équipes)
  • Besoin de scalabilité différenciée
  • Technologies différentes par service
  • Déploiements fréquents indépendants
  • Tolérance aux pannes par service

Éviter pour: petites équipes, prototypes, applications simples.


Question 3: Qu'est-ce que le Service Discovery?

Réponse: Mécanisme permettant aux services de se trouver dynamiquement sans configuration statique des adresses IP.

Service A: "Où est Service B?"
↓
Eureka Server: "Service B est à 192.168.1.10:8081 et 192.168.1.11:8081"
↓
Service A appelle Service B

Question 4: Qu'est-ce qu'un API Gateway?

Réponse: Point d'entrée unique pour tous les microservices:

  • Routage vers les services
  • Authentification centralisée
  • Rate limiting
  • Load balancing
  • Logging/Monitoring
Client → API Gateway → Service A
→ Service B
→ Service C

Question 5: Qu'est-ce qu'un Circuit Breaker?

Réponse: Pattern de résilience qui "coupe" les appels vers un service défaillant:

États:
CLOSED → Appels normaux
OPEN → Appels bloqués (fallback)
HALF_OPEN → Test de récupération

Empêche les cascades de pannes.

Question 6: Qu'est-ce que le pattern Saga?

Réponse: Gestion des transactions distribuées via une séquence de transactions locales avec compensations:

Order → Payment → Inventory → Shipping
↓ (échec)
Compensation: rembourser

Chaque service gère sa transaction et peut annuler (compenser) si nécessaire.


Question 7: Qu'est-ce que CQRS?

Réponse: Command Query Responsibility Segregation - séparer les opérations de lecture et d'écriture:

Commandes (Write) → Command Service → Write DB
Requêtes (Read) → Query Service → Read DB (optimisée)

Permet d'optimiser chaque côté indépendamment.


Question 8: Qu'est-ce que l'Event Sourcing?

Réponse: Stocker tous les événements plutôt que l'état actuel:

Events:
1. UserCreated {id: 1, name: "John"}
2. UserEmailChanged {id: 1, email: "john@new.com"}
3. UserDeleted {id: 1}

État = replay de tous les événements

Avantages: audit complet, reconstruction d'état, event replay.


Question 9: Quels sont les 12 facteurs d'une application cloud-native?

Réponse:

  1. Codebase: un repo, plusieurs déploiements
  2. Dependencies: déclarées et isolées
  3. Config: dans l'environnement
  4. Backing services: traités comme ressources attachées
  5. Build, release, run: étapes strictement séparées
  6. Processes: stateless
  7. Port binding: auto-contenu
  8. Concurrency: scale horizontal
  9. Disposability: démarrage/arrêt rapides
  10. Dev/prod parity: environnements similaires
  11. Logs: flux d'événements
  12. Admin processes: tâches ponctuelles

Question 10: Comment gérer la communication inter-services?

Réponse:

TypeProtocoleUsage
SynchroneREST/gRPCRéponse immédiate requise
AsynchroneRabbitMQ/KafkaDécouplage, events

Préférer asynchrone quand possible pour la résilience.


Questions 11-20: Spring Cloud​

Question 11: Comment configurer Eureka Server?

Réponse:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication { }
server:
port: 8761

eureka:
client:
register-with-eureka: false
fetch-registry: false

Question 12: Comment enregistrer un service dans Eureka?

Réponse:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
spring:
application:
name: user-service

eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/

Question 13: Comment appeler un autre service avec RestTemplate et load balancing?

Réponse:

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}

@Service
public class OrderService {

private final RestTemplate restTemplate;

public User getUser(Long id) {
// Utilise le nom du service, pas l'URL
return restTemplate.getForObject(
"http://user-service/api/users/" + id, User.class);
}
}

Question 14: Comment utiliser OpenFeign pour les appels inter-services?

Réponse:

@EnableFeignClients
@SpringBootApplication
public class OrderApplication { }

@FeignClient(name = "user-service")
public interface UserClient {

@GetMapping("/api/users/{id}")
User getUser(@PathVariable Long id);
}

@Service
public class OrderService {

private final UserClient userClient;

public Order createOrder(OrderRequest req) {
User user = userClient.getUser(req.getUserId());
// ...
}
}

Question 15: Comment configurer Spring Cloud Config Server?

Réponse:

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication { }
server:
port: 8888

spring:
cloud:
config:
server:
git:
uri: https://github.com/org/config-repo
default-label: main

Question 16: Comment un service client utilise Config Server?

Réponse:

# bootstrap.yml
spring:
application:
name: user-service
cloud:
config:
uri: http://localhost:8888

Le service récupère user-service.yml depuis le Config Server.


Question 17: Comment configurer Spring Cloud Gateway?

Réponse:

spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1

- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
- Method=GET,POST

Question 18: Comment ajouter un filtre global dans Gateway?

Réponse:

@Component
public class LoggingFilter implements GlobalFilter, Ordered {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("Request: {} {}",
exchange.getRequest().getMethod(),
exchange.getRequest().getPath());

return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("Response: {}",
exchange.getResponse().getStatusCode());
}));
}

@Override
public int getOrder() {
return -1;
}
}

Question 19: Comment configurer Resilience4j Circuit Breaker?

Réponse:

resilience4j:
circuitbreaker:
instances:
userService:
slidingWindowSize: 10
failureRateThreshold: 50
waitDurationInOpenState: 10000
permittedNumberOfCallsInHalfOpenState: 3
@CircuitBreaker(name = "userService", fallbackMethod = "fallback")
public User getUser(Long id) {
return userClient.getUser(id);
}

public User fallback(Long id, Exception ex) {
return new User(id, "Fallback User", "N/A");
}

Question 20: Comment configurer le retry avec Resilience4j?

Réponse:

resilience4j:
retry:
instances:
userService:
maxAttempts: 3
waitDuration: 1000
enableExponentialBackoff: true
exponentialBackoffMultiplier: 2
@Retry(name = "userService")
@CircuitBreaker(name = "userService", fallbackMethod = "fallback")
public User getUser(Long id) {
return userClient.getUser(id);
}

Questions 21-30: Patterns Avancés​

Question 21: Comment implémenter un fallback avec Feign?

Réponse:

@FeignClient(name = "user-service", fallbackFactory = UserClientFallback.class)
public interface UserClient {
@GetMapping("/api/users/{id}")
User getUser(@PathVariable Long id);
}

@Component
public class UserClientFallback implements FallbackFactory<UserClient> {

@Override
public UserClient create(Throwable cause) {
return id -> new User(id, "Fallback", "N/A");
}
}

Question 22: Comment implémenter le rate limiting dans Gateway?

Réponse:

spring:
cloud:
gateway:
routes:
- id: api-route
uri: lb://api-service
predicates:
- Path=/api/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
key-resolver: "#{@userKeyResolver}"
@Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getRemoteAddress().getHostName()
);
}

Question 23: Comment rafraîchir la configuration à chaud?

Réponse:

@RefreshScope
@RestController
public class ConfigController {

@Value("${app.message}")
private String message;

@GetMapping("/message")
public String getMessage() {
return message;
}
}
# Déclencher le refresh
curl -X POST http://localhost:8080/actuator/refresh

Ou avec Spring Cloud Bus pour propager à tous les services.


Question 24: Comment tracer les requêtes distribuées?

Réponse: Avec Micrometer Tracing (ex-Sleuth) + Zipkin:

<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
</dependency>
management:
tracing:
sampling:
probability: 1.0
zipkin:
tracing:
endpoint: http://zipkin:9411/api/v2/spans

Chaque requête a un traceId unique propagé entre services.


Question 25: Comment sécuriser les communications inter-services?

Réponse:

  1. mTLS: certificats mutuels
  2. JWT propagation: token passé entre services
  3. Service mesh: Istio, Linkerd
  4. Network policies: Kubernetes
// JWT propagation avec Feign
@Configuration
public class FeignConfig {

@Bean
public RequestInterceptor authInterceptor() {
return template -> {
String token = SecurityContextHolder.getContext()
.getAuthentication().getCredentials().toString();
template.header("Authorization", "Bearer " + token);
};
}
}

Question 26: Comment gérer les secrets en microservices?

Réponse:

  1. Spring Cloud Config avec encryption
  2. Vault (HashiCorp)
  3. Kubernetes Secrets
  4. AWS Secrets Manager / Azure Key Vault
# Config Server avec encryption
spring:
cloud:
config:
server:
encrypt:
enabled: true

encrypt:
key: ${ENCRYPT_KEY}

Question 27: Comment gérer les versions d'API?

Réponse:

  1. URL versioning: /api/v1/users
  2. Header versioning: Accept: application/vnd.api.v1+json
  3. Query param: /api/users?version=1
@RestController
@RequestMapping("/api/v1/users")
public class UserControllerV1 { }

@RestController
@RequestMapping("/api/v2/users")
public class UserControllerV2 { }

Question 28: Comment déployer des microservices avec Kubernetes?

Réponse:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: user-service:1.0
ports:
- containerPort: 8080
env:
- name: EUREKA_SERVER
value: "http://eureka:8761/eureka"
---
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- port: 80
targetPort: 8080

Question 29: Comment monitorer les microservices?

Réponse:

  1. Métriques: Prometheus + Grafana
  2. Logs: ELK Stack (Elasticsearch, Logstash, Kibana)
  3. Traces: Zipkin / Jaeger
  4. Alerting: Prometheus Alertmanager

Dashboard centralisé avec:

  • Latence par service
  • Taux d'erreur
  • Throughput
  • Dépendances

Question 30: Quelles sont les bonnes pratiques microservices?

Réponse:

  1. Bounded context: un service = un domaine métier
  2. Database per service: pas de DB partagée
  3. API contracts: OpenAPI/Swagger
  4. Idempotence: opérations répétables sans effet
  5. Healthchecks: Actuator pour chaque service
  6. Circuit breakers: protection contre les pannes
  7. Async communication: préférer quand possible
  8. Centralized logging: corrélation par traceId
  9. Infrastructure as Code: Terraform, Helm
  10. Feature flags: déploiement progressif

Score​

ScoreNiveau
27-30Excellent - Microservices maîtrisés
21-26Bien - Quelques révisions
15-20Moyen - Relisez les chapitres
Moins de 15À revoir

Retour au Module 13