Dans ce hands-on-lab
nous allons nous intéresser aux architectures de microservices et à la problématique de leur réactivité aux évènements d'un système commun.
Un microservice est dédié à une tâche atomatique, permettant de rendre nos architectures plus faciles à scaler
et à superviser.
Toutefois, la multiplication des processus mène à une exécution de nos cas d'utilisation au sein de transactions distribuées, soulevant la question de leur gestion.
Une solution serait de créer des microservices composites, ou bien, pour ceux qui n'ont pas peur des ESB
, afin de gérer la transaction.
Sinon, on peut aussi piloter nos microservices par les évènements, en les rendant réactifs aux résultats des processus en amont de la transaction distribuée dont ils font partie.
+------------+
| Service A |
|------------|
| ETAPE A |
+------------+
^
| Ecoute
|
+------------+
| Service B |
| |
| ETAPE B |
+-----+------+
^
| Ecoute
|
+-----+------+
| Service C |
|------------|
| ETAPE C |
+------------+
C'est à ce type de solution que nous allons nous intéresser en s'appuyant sur l'écosystème Java
.
L'idée est de se pencher sur les technologies innovantes qui seront stables à l'horizon 2017 plutôt que de travailler avec des fonctionnalités production ready
.
Nous allons créer notre application web à partir de Spring Boot
ainsi que le module experimental Reactive Web
de Spring 5
.
Pour créer notre application, on pourra utiliser http://start.spring.io avec le module Reactive Web
(pensez bien à choisir Spring Boot 2.0.0
).
Pour le support des Reactive Streams
, l'équipe Spring
à décider d'utiliser Reactor
: https://github.com/reactor/reactor-core
On s'appuiera sur une base de données orientée document: Couchbase
.
Je vous fournirai l'adresse d'une instance hébergée chez Amazon.
Enfin, si on a le temps, on essayera de faire transiter nos évènements via un MOM
(Message Oriented Middleware): Kafka
.
Il suffira de la télécharger ici (0.10.0.1
): https://kafka.apache.org/downloads.html
Java 8
sera nécessaire: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
Nous allons implémenter un chat basique où plusieurs personnes peuvent s'échanger des messages. On souhaite stocker tous nos message en base de données. Le code sera structuré de façon à pouvoir très facilement isoler chaque étape dans une méthode spécifique, qui pourraient être hébergées dans des microservices dédiés :
- Ecriture et envoi d'un message
- Enregistrement du message
- Réception du message par les autres utilisateur
Créer un microservice spring boot en charge d'exposer 3 endpoints
:
/
qui affichera la pageHTML
du chat/message
(GET
) pour ouvrir une connexionSSE
suspendue parSpring
utilisée pour recevoir les messages/message
(POST
) pour ouvrir un envoyer un message à tous les autres utilisateurs connectés
Pour initialiser une connexion SSE
, vous pouvez vous appuyer sur l'example suivant :
var eventSource = new EventSource("/message");
eventSource.onmessage = function(e) {
console.log(e.data);
};
Afin de créer un flux de message, on peut s'appuyer sur l'élément Flux de Reactor
.
Si notre endpoint
retourne un Flux<ServerSentEvent>
, Spring
va correctement interprêter la connexion SSE
et la suspendre.
On souhaite modéliser un méchanisme de pubsub
(Publish/Subscribe) où plusieurs clients, les connexions SSE
, font un susbcribe
sur un publisher
commun (le WS /message
).
Le TopicProcessor est un Flux
qui permet de créer ce type de comportement.
Inspirez-vous d'un exemple ici: https://github.com/reactor/reactor-core#async-pub-sub--topicprocessor
Lorsque l'on poste un message, nous allons maintenant le sauvegarder dans Couchbase
avant de le soumettre au TopicProcessor
.
Couchbase propose un driver
asynchrone permettant de réaliser des opérations selon le stanndard des Reactive Streams
.
RxJava
est utilisé par Couchbase
plutôt que Reactor
.
Cela n'a pas d'importance, on peut manipuler un Observable
auquel on peut souscrire un handler
notifié lorsque notre message est suvegardé.
L'idée est d'envoyer le message au TopicProcessor
qu'une fois que notre message a été sauvegardé.
Un exemple se trouve ici: http://developer.couchbase.com/documentation/server/4.0/sdks/java-2.2/documents-creating.html
Dans l'exercice précédent nous, avons créé un couplage fort entre la sauvegarde d'un document et l'envoi d'un message aux connexions SSE
.
Cela est contraire aux architecture de microservice.
Nous allons adopter une méthode différente: enregistrer le document et démarrer un processus annexe qui sera notifié par Couchbase
lorsque le document est enregistré.
Pour cela, on va s'appuyer sur le DCP
(database change protocol) supporté par Couchbase
.
Un exemple se trouve ici : https://github.com/couchbaselabs/java-dcp-client#basic-usage
Je vous donnerai l'adresse d'un serveur Couchbase
à utiliser.
C'est que les choses deviendront intéressantes, car cela nous permettra de s'envoyer des messages les uns aux autres :-)
TODO (Kafka)