À mesure que les applications grandissent, les patterns synchrones requête-réponse deviennent un goulot d'étranglement. L'architecture événementielle (EDA) offre une alternative puissante : les composants communiquent via des événements, leur permettant de scaler et échouer indépendamment sans affecter l'ensemble du système. Dans cet article, nous plongeons dans les concepts clés de l'EDA, des message brokers à l'event sourcing et CQRS.
Les Message Brokers : le cœur de l'EDA
Un message broker agit comme intermédiaire entre les producteurs (services qui publient des événements) et les consommateurs (services qui traitent les événements). Apache Kafka, RabbitMQ et Amazon SQS sont les options les plus utilisées, chacune avec ses propres forces. Kafka excelle dans le streaming d'événements à haut débit avec un stockage durable, tandis que RabbitMQ est plus flexible avec des patterns de routage comme les topic exchanges et les dead letter queues.
Le choix du bon broker dépend de votre cas d'usage : avez-vous besoin d'une livraison garantie ? De capacités de replay d'événements ? Quelle est l'importance de l'ordonnancement ? Kafka offre un ordonnancement au niveau des partitions et la compaction de logs, tandis que RabbitMQ fournit des garanties de livraison plus fortes avec les acknowledgments et les contrôles de prefetch.
// Producteur d'événements avec Kafka (Node.js)
const { Kafka } = require('kafkajs');
const kafka = new Kafka({
clientId: 'order-service',
brokers: ['kafka-1:9092', 'kafka-2:9092']
});
const producer = kafka.producer();
await producer.connect();
// Publier un événement OrderCreated
await producer.send({
topic: 'order-events',
messages: [{
key: orderId,
value: JSON.stringify({
type: 'OrderCreated',
payload: { orderId, items, total },
timestamp: Date.now(),
correlationId: uuid()
})
}]
});
Event Sourcing et CQRS
L'Event Sourcing stocke chaque changement d'état comme un événement immuable dans un event store en mode append-only. Au lieu de ne conserver que l'état actuel, vous disposez d'un journal d'audit complet de tous les changements. Cela permet de reconstruire l'état à n'importe quel moment, ce qui est inestimable pour le débogage, la conformité et l'analytique.
CQRS (Command Query Responsibility Segregation) sépare les opérations de lecture et d'écriture en modèles distincts. Le modèle de commande traite les actions d'écriture et publie des événements, tandis que le modèle de requête maintient des vues de lecture optimisées. Cette séparation permet de scaler et d'optimiser chaque modèle indépendamment pour sa tâche spécifique.
- Utilisez des consumers idempotents pour gérer les événements en double en toute sécurité
- Implémentez des dead letter queues pour les événements non traitables
- Ajoutez correlationId et causationId à chaque événement pour la traçabilité
- Envisagez un schema registry (Avro/Protobuf) pour la gestion des contrats d'événements
- Commencez simple : tous les systèmes n'ont pas besoin d'event sourcing
- Surveillez le consumer lag pour détecter les goulots d'étranglement tôt
Patterns de gestion d'erreurs et résilience
Dans les systèmes distribués événementiels, les pannes sont inévitables. Le pattern Saga coordonne les transactions à travers plusieurs services en définissant des actions compensatoires pour chaque étape. Si le service de paiement échoue après la création d'une commande, la saga envoie automatiquement un événement compensatoire pour annuler la commande.
Implémentez des circuit breakers autour des appels de services externes et utilisez le backoff exponentiel avec jitter pour les retries. Combinez cela avec des dead letter queues et de l'alerting pour qu'aucun événement ne soit définitivement perdu. Envisagez également le pattern Outbox pour une publication d'événements fiable : écrivez les événements dans une table outbox dans la même transaction de base de données que votre changement de domaine, et laissez un processus séparé les publier vers le message broker.
Conseil Pro
Commencez par un simple setup pub/sub avec RabbitMQ ou Amazon SQS pour votre premier flux événementiel. Identifiez un appel API synchrone dans votre système qui constitue un goulot d'étranglement et remplacez-le par un événement asynchrone. Mesurez l'impact sur la latence et le débit. Vous constaterez que même ce petit pas apporte déjà des améliorations significatives en termes de scalabilité et de résilience du système.
Partager cet article