Developpez.com

Plus de 14 000 cours et tutoriels en informatique professionnelle à consulter, à télécharger ou à visionner en vidéo.

Tutoriel sur le développement d'une application basée sur une architecture microservice avec Docker

L'objectif de cette quatrième série d'exercices est d'apprendre à construire une application en respectant une architecture à base de microservices. Nous utiliserons pour cela plusieurs technologies : la bibliothèque KumuluzEE pour packager et exécuter une application Java EE en ligne de commande, l'outil Docker pour l'isolation des microservices, la bibliothèque et le serveur RabbitMQ pour la gestion d'un bus d'événements afin que les microservices communiquent de manière asynchrone et finalement l'outil Docker Compose pour la composition des microservices.

La grande majorité du code contenu dans les microservices vous sera donnée comme support. En effet, ces exercices se focaliseront principalement sur les problématiques de déploiement.

Dans la suite, on appelle « microservice », un programme qui implémente une fonctionnalité dans un langage donné (par exemple Java) et qui est isolé dans un conteneur Docker.

Nous invitons les lecteurs à consulter les deux supports de cours qui présentent les concepts mis en avant dans cette série d'exercices :

Pour réagir au contenu de ce tutoriel, un espace de dialogue vous est proposé sur le forum 4 commentaires Donner une note à l'article (5).

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Prérequis logiciels

Avant de démarrer cette série d'exercices, veuillez préparer votre environnement de développement en installant les outils suivants :

Eclipse, Java et Maven sont nécessaires uniquement pour la partie liée à KumuluzEE. Même si ces outils ne sont pas installés, vous pourrez sans problème réaliser les exercices puisque nous ferons la compilation Java lors de la création d'une image Docker.

Toutes les expérimentations se feront sur un poste en local à partir d'un système d'exploitation Linux. Vous pouvez sans problème réaliser ces expérimentations depuis les systèmes OS X ou Windows en utilisant Docker Toolbox (voir l'installation de Docker pour ces systèmes) ou via Vagrant par exemple. Dans tous les cas où vous utiliserez une virtualisation, vous aurez à rediriger les ports réseaux suivants :

  • 6379 : port utilisé par le serveur Redis ;
  • 15672 et 5672 : ports utilisés par RabbitMQ (interface de gestion de RabbitMQ et serveur RabbitMQ) ;
  • 80: pour la redirection du port http.

II. Présentation de l'étude de cas

L'étude de cas utilisée est une application permettant de diffuser des HelloWorld. Elle fournit une interface web pour la saisie et pour la consultation des HelloWorld.

Interface web pour la saisie et l'affichage

Sur le schéma proposé ci-dessous, nous détaillons la décomposition en microservices de l'application HelloWorld.

Architecture de l'application HelloWorld

L'architecture dispose de sept microservices.

  • Le microservice Web (contenu dans le projet helloworldwebmicroservice) fournit à l'utilisateur une interface web. La technologie utilisée sera du HTML/JavaScript pour le client et NodeJS pour créer un petit serveur web.
  • Le microservice Rest (contenu dans le projet helloworldrestmicroservice) a pour rôle de fournir une API de type service web pour le microservice Web. Lors de la réception d'un HelloWorld celui-ci est envoyé au microservice Redis à des fins de stockage. Il publie également un événement vers le microservice RabbitMQ.
  • Le microservice Redis fournit un serveur Redis pour le stockage des HelloWorld.
  • Le microservice RabbitMQ fournit un bus d'événements basé sur RabbitMQ.
  • Le microservice Log (contenu dans le projet helloworldlogmicroservice) s'abonne au bus d'événements et affiche sur la sortie console les événements envoyés.
  • Les microservices Email et Twitter s'abonnent au bus d'événement et envoient respectivement un email ou un tweet. Ces deux microservices ne seront pas traités.

III. Exercice 1 : Préparer le programme Java du service web HelloWorld (Rest)

III-A. But

  • Configurer un programme Java EE avec KumuluzEE.
  • Configurer un pom.xml pour gérer les dépendances Maven.
  • Exécuter un programme Java EE en ligne de commande.

III-B. Description

Le projet Java (celui qui servira pour le microservice Rest) du service web HelloWorld a été développé en utilisant les spécifications Java EE à savoir JAX-RS et CDI. Les implémentations choisies pour JAX-RS et CDI sont issues de JERSEY. Elles sont fournies par KumuluzEE qui joue alors le rôle d'intermédiaire. Le code du projet Java est assez commun. Un package service pour la gestion des services web REST et un package dao pour la gestion des données avec la base de données Redis. Dans cet exercice on va partir d'un code déjà tout prêt et nous allons nous attacher à le configurer pour l'utiliser avec KumuluzEE.

Concernant plus spécifiquement KumuluzEE, il s'agit d'un très jeune projet qui a remporté le Duke's Choice Award 2015 à Java One 2015. KumuluzEE s'appuie sur les standards Java EE pour les briques logiciels (JAX-RS, JPA, CDI…). Aucune nouvelle API n'est proposée en dehors de Java EE et tout ce que vous savez déjà faire avec Java EE reste valide.

III-C. Étapes à suivre

  • Téléchargez le fichier helloworldmicroservices.zip contenant tous les squelettes des projets décrivant les microservices.
  • Démarrez l'environnement de développement Eclipse.
  • Importez le projet Maven helloworldrestmicroservice (File -> Import -> General -> Existing Projects into Workspace et choisissez l'option Select root directory puis sélectionnez le répertoire).
  • Examinez les différents packages et classes. Vous remarquerez que le projet contient des erreurs de compilation dues à l'absence des dépendances vers KumuluzEE et indirectement vers JERSEY.
  • Ouvrez le fichier pom.xml et complétez le contenu de la balise <dependencies> par les dépendances suivantes :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
...
    <dependencies>
        <dependency>
            <groupId>com.kumuluz.ee</groupId>
            <artifactId>kumuluzee-core</artifactId>
            <version>${kumuluzee.version}</version>
        </dependency>
        <dependency>
            <groupId>com.kumuluz.ee</groupId>
            <artifactId>kumuluzee-servlet-jetty</artifactId>
            <version>${kumuluzee.version}</version>
        </dependency>
        <dependency>
            <groupId>com.kumuluz.ee</groupId>
            <artifactId>kumuluzee-jax-rs</artifactId>
            <version>${kumuluzee.version}</version>
        </dependency>
        <dependency>
            <groupId>com.kumuluz.ee</groupId>
            <artifactId>kumuluzee-cdi</artifactId>
            <version>${kumuluzee.version}</version>
        </dependency>
        ...
    </dependencies>
...
  • Complétez dans la balise <properties> le numéro de version de KumuluzEE. Celle-ci est à 1.0.0 puisque le projet KumuluzEE est encore très jeune :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
...
    <properties>
        <kumuluzee.version>1.0.0</kumuluzee.version>
        ...
    </properties>
...

Désormais le projet ne contient plus d'erreur et peut être compilé en totalité (Eclipse s'en charge via la compilation incrémentale).

  • Pour exécuter le projet depuis Eclipse, créez une configuration d'exécution que vous appellerez HelloworldRESTMicroservice et dont la classe principale (Main class) sera com.kumuluz.ee.EeApplication puis faire Run.

Votre programme s'exécute par l'intermédiaire de KumuluzEE. Pour tester, nous pourrions utiliser l'adresse http://localhost:8080/helloworld, mais comme le serveur Redis n'est pas encore opérationnel nous ne pourrons pas à cet instant aller plus loin dans les tests.

  • Avant de continuer, arrêtez l'exécution du programme depuis le bouton Terminate (bouton rouge) de la console Eclipse.
  • Notre programme Java doit s'exécuter en ligne de commande et non pas depuis Eclipse quand il sera exécuté depuis un conteneur Docker. Nous allons donc réaliser une dernière modification sur le fichier pom.xml afin de préparer le terrain. Nous allons préciser à Maven que l'on souhaite que toutes les dépendances soient présentes dans le répertoire target du projet. Ouvrez donc le fichier pom.xml.
  • Ajoutez dans la balise <plugins> le plugin maven-dependency-plugin comme montré sur le code suivant :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
...
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.10</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
  • Depuis Eclipse, exécutez la configuration d'exécution appelée alldependencies (package). Si vous rencontrez des soucis avec l'intégration Maven sous Eclipse, exécutez la commande shell suivante à la racine de votre projet $ mvn package. Toutes les dépendances seront copiées par le plugin maven-dependency-plugin et localisées dans le répertoire helloworldrestmicroservice/target/dependency.
  • Ouvrez une invite de commande shell à la racine du projet helloworldrestmicroservice, puis exécutez la ligne de commande suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
$ java -cp 'target/classes:target/dependency/*' com.kumuluz.ee.EeApplication
...
2016-01-31 08:00:18.278:INFO:oejs.ServerConnector:main: Started ServerConnector@77b325b3{HTTP/1.1}{0.0.0.0:8080}
2016-01-31 08:00:18.278:INFO:oejs.Server:main: Started @1523ms
janv. 31, 2016 8:00:18 AM com.kumuluz.ee.jetty.JettyServletServer startServer
INFOS: Jetty started
janv. 31, 2016 8:00:18 AM com.kumuluz.ee.EeApplication initialize
INFOS: KumuluzEE started successfully

Votre application Java EE est désormais opérationnelle et l'instruction pour la démarrer fonctionne.

  • Arrêtez l'exécution du programme en faisant simplement un CTRL-C.
  • Avant de passer à l'exercice suivant qui nous permettra de disposer d'un serveur Redis, essayons de comprendre comment la communication est réalisée entre l'application Java EE et le serveur Redis. Ouvrez la classe fr.mickaelbaron.helloworldrestmicroservice.dao.redis.JedisFactory et examinez la méthode URI getRedisURI() :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
private static final String REDISALIAS_PORT_ENV_KEY = "REDISALIAS_PORT";

private URI getRedisURI() {
  String redisPort = System.getenv(REDISALIAS_PORT_ENV_KEY);
  return URI.create(redisPort != null && !redisPort.isEmpty() ? redisPort : "tcp://localhost:6379");
}

Vous remarquerez que l'accès à l'hôte de Redis se fait par une variable d'environnement REDISALIAS_PORT (qui sera utilisée plus tard quand le projet sera un microservice) ou se fait via l'adresse localhost (pratique pour les tests).

IV. Exercice 2 : Préparer le microservice Redis (créer un conteneur à partir d'une image existante)

IV-A. But

  • Récupérer depuis Docker Hub une image prête à l'emploi.
  • Créer un conteneur depuis une image avec un volume, une redirection d'un port et un paramètre d'exécution (surcharge de la commande CMD).
  • Lister des images Docker.
  • Lister les conteneurs disponibles.
  • Inspecter un conteneur.

IV-B. Description

Le microservice Redis a pour objectif de conserver l'état des différents HelloWorld traités par le microservice Rest. Cette conservation de données se fera par l'intermédiaire d'un serveur Redis. Ce serveur permettra au microservice Rest Java de s'y connecter afin de conserver la création des HelloWorld.

IV-C. Étapes à suivre

  • Allez sur le site Docker Hub et faites une recherche sur Redis. Vous remarquerez un nombre important de dépôts (« Repositories ») destinés à Redis. De manière générale, veuillez privilégier les dépôts officiels.
  • Ouvrez une invite de commande shell et placez-vous à la racine du dossier helloworldmicroservices.
  • Saisissez la commande shell suivante pour télécharger la dernière version de l'image Docker Redis. Cela prendra un petit peu de temps, car toutes les couches (« layers ») de l'image doivent être téléchargées. À noter que chaque couche est une image qui fait référence à une image parente :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
$ docker pull redis
Using default tag: latest
latest: Pulling from library/redis
dbacfa057b30: Pull complete
7a01cc5f27b1: Pull complete
18a8857eed52: Pull complete
...
f211cd551a8f: Pull complete
7fd87e96bac5: Pull complete
ce8fb9edd365: Pull complete
678a090a2546: Pull complete
Status: Downloaded newer image for redis:latest
  • Assurez-vous que l'image a été correctement téléchargée en utilisant la commande images de l'outil docker :
 
Sélectionnez
1.
2.
3.
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
redis               latest              678a090a2546        32 hours ago        151.2 MB
  • Les différentes couches de l'image peuvent être consultées en utilisant la commande history de l'outil docker :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
$ docker history redis
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
678a090a2546        32 hours ago        /bin/sh -c #(nop) CMD ["redis-server"]          0 B
ce8fb9edd365        32 hours ago        /bin/sh -c #(nop) EXPOSE 6379/tcp               0 B
7fd87e96bac5        32 hours ago        /bin/sh -c #(nop) ENTRYPOINT &{["/entrypoint.   0 B
f211cd551a8f        32 hours ago        /bin/sh -c #(nop) COPY file:005b4fdd83cc15dfc   109 B
...
18a8857eed52        5 days ago          /bin/sh -c groupadd -r redis && useradd -r -g   330.4 kB
7a01cc5f27b1        5 days ago          /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B
dbacfa057b30        5 days ago          /bin/sh -c #(nop) ADD file:e5a3d20748c5d3dd5f   125.1 MB
  • Nous pouvons désormais, créer un conteneur à partir de l'image Docker de Redis. Saisissez la commande shell suivante :
 
Sélectionnez
1.
2.
$ docker run --name redis -v /var/redis:/data -d redis redis-server --appendonly yes
2ff680b66e206442abbf6836a406405e0b4572dd8394454cebdfaf0c70e3172f
  • Vérifions que le conteneur a été créé en utilisant la commande shell suivante :
 
Sélectionnez
1.
2.
3.
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
2ff680b66e20        redis               "/entrypoint.sh redis"   5 hours ago         Up 5 hours          6379/tcp            redis

Nous venons de créer dans un conteneur une instance d'un serveur Redis. Nous allons pouvoir l'utiliser pour tester notre programme Java.

V. Exercice 3 : Tester le service web HelloWorld (Rest) avec le microservice Redis

V-A. But

  • Redirection de ports avec Docker.
  • Inspection des métadonnées d'un conteneur Docker.

V-B. Description

Revenons un instant sur le test du projet helloworldrestmicroservice (voir premier exercice). Pour assurer la communication entre ce projet et le microservice Redis deux solutions s'offrent à nous. La première est de récupérer l'adresse IP du conteneur. La seconde est de rediriger le port 6379 (le port par défaut de Redis) du conteneur vers le port 6379 de l'hôte. Voyons rapidement en pratique ces deux solutions.

V-C. Étapes à suivre

  • Pour la récupération de l'adresse du conteneur, veuillez utiliser la commande inspect de l'outil docker. Le retour de la commande inspect retourne un document JSON. Via l'option --format il est possible de formater la sortie pour extraire la bonne information :
 
Sélectionnez
1.
2.
$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' redis
172.17.0.2

À noter que l'outil JQ peut être utilisé pour effectuer des recherches plus approfondies :

 
Sélectionnez
1.
2.
$ docker inspect redis | jq -r '.[0] | .NetworkSettings.IPAddress'
172.17.0.2
  • Depuis la configuration d'exécution, ajoutez une variable d'environnement appelée (onglet Environment) REDISALIAS_PORT avec la valeur tcp://172.17.0.2:6379, puis faites Run.
  • Pour tester le service web HelloWorld, nous utiliserons l'outil curl. Exécutez les commandes shell suivantes :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
# Création d'un HelloWorld à partir d'un contenu JSON
$ curl -H "Content-Type: application/json" -X POST -d '{"message":"Mon HelloWorld"}' http://localhost:8080/helloworld

# Lister les HelloWorld
$ curl http://localhost:8080/helloworld
[{"rid":1,"message":"Mon HelloWorld","startDate":"Sun Jan 31 16:42:35 CET 2016"}]

Tout fonctionne parfaitement. Voyons maintenant la seconde solution pour faire communiquer notre programme Java et le microservice Redis.

  • Arrêtez l'exécution du programme depuis le bouton Terminate (bouton rouge) de la console Eclipse et supprimez depuis la configuration d'exécution la variable d'environnement REDISALIAS_PORT.
  • Pour la redirection du port 6379 du conteneur vers le port 6379 del'hôte vous devez ajouter un paramètre lors de la construction du conteneur : -p 6379:6379. Exécutez la ligne de commande shell suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
# On supprime le précédent conteneur (avec l'option -f on force l'arrêt et la suppression)
$ docker rm -f redis

# On crée de nouveau le conteneur
$ docker run --name redis -v /var/redis:/data -p 6379:6379 -d redis redis-server --appendonly yes
  • Exécutez le projet helloworldrestmicroservice depuis Eclipse à partir de la configuration d'exécution HelloworldRESTMicroservice et testez de nouveau le fonctionnement du service web HelloWorld.

Tout fonctionne parfaitement. Notre programme Java du service web HelloWorld est prêt à être isolé dans un conteneur Docker afin de devenir un microservice.

VI. Exercice 4 : Préparer le microservice Rest (écrire un Dockerfile et créer sa propre image Docker)

VI-A. But

  • Construction d'un fichier Dockerfile.
  • Construction d'une image Docker.
  • Isoler un programme Java.

VI-B. Description

Le microservice Rest a pour objectif d'isoler dans un conteneur Docker le projet Java du service web HelloWorld. Une image Docker à base de Java et de Maven sera utilisée. Elle sera construite en s'assurant que le projet Maven compile correctement.

VI-C. Étapes à suivre

  • Créez un fichier Dockerfile à la racine du projet helloworldrestmicroservice.
  • Ouvrez un éditeur de texte et saisissez le contenu présenté ci-dessous :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
FROM java:openjdk-8-jdk
MAINTAINER Mickael BARON

ENV MAVEN_VERSION 3.3.9
RUN curl -fsSLk https://archive.apache.org/dist/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz | tar xzf - -C /usr/share \
    && mv /usr/share/apache-maven-$MAVEN_VERSION /usr/share/maven \
    && ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
ENV MAVEN_HOME /usr/share/maven

ADD pom.xml /work/pom.xml
WORKDIR /work
RUN ["mvn", "dependency:go-offline"]

ADD ["src", "/work/src"]
RUN ["mvn", "package"]

EXPOSE 8080
ENTRYPOINT ["java", "-cp", "target/classes:target/dependency/*", "com.kumuluz.ee.EeApplication"]

Donnons quelques détails sur le contenu de ce fichier. À la ligne 1, il est précisé que l'image que nous souhaitons construire se basera sur une image fournissant Java 8. De la ligne 4 à la ligne 8, nous précisons comment doit être installé Maven. La ligne 10 précise que le fichier pom.xml sera copié dans le répertoire /work/pom.xml de l'image. La ligne 11 indique que le répertoire courant sera /work. La ligne 12 demande à Maven de télécharger tout ce dont il a besoin. L'avantage de procéder de cette manière c'est que si vous modifiez le code source de votre projet, les dépendances n'auront pas à être de nouveau téléchargées puisqu'elles auront été faites avant. Toutefois, si vous modifiez le fichier pom.xml, la reconstruction de l'image se fera à partir de la ligne 10. La ligne 14 précise que le répertoire src sera copié dans le répertoire /work/src de l'image. À la ligne 15, il est demandé de faire une construction de package via Maven. À la ligne 17, il est indiqué que le port 8080 sera exposé. Enfin à la ligne 18, il est indiqué comment démarrer le programme Java. La ligne de commande est identique à celle que nous avions vue dans l'exercice 1.

  • Nous allons construire l'image à partir de fichier Dockerfile, exécutez la ligne de commande shell suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
$ docker build -t mickaelbaron/helloworldrestmicroservice .
... // Construction de l'image
Step 08 : RUN mvn dependency:go-offline
---> Running in f0afa8232c86
[INFO] Scanning for projects...
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.10/maven-dependency-plugin-2.10.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.10/maven-dependency-plugin-2.10.pom (12 KB at 20.7 KB/sec)
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/27/maven-plugins-27.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/27/maven-plugins-27.pom (12 KB at 152.0 KB/sec)
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/26/maven-parent-26.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/26/maven-parent-26.pom (39 KB at 479.7 KB/sec)
Downloading: https://repo.maven.apache.org/maven2/org/apache/apache/16/apache-16.pom
...

Veuillez remarquer le téléchargement des dépendances Java (les fichiers Jar) réalisées lors de la commande $mvn dependendy:go-offline.

  • Vérifiez que l'image a été correctement construite en exécutant la ligne de commande shell suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
$ docker images
REPOSITORY                                TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
mickaelbaron/helloworldrestmicroservice   latest              c743275a2e56        22 seconds ago      700.9 MB
redis                                     latest              678a090a2546        2 days ago          151.2 MB
java                                      openjdk-8-jdk       79b6c926116e        5 days ago          642.2 MB

Vous remarquerez que l'image java est disponible puisque l'image que nous venons de construire est basée sur celle-ci. Notez également la taille de notre image 700.9 MB. En fait l'image mickaelbaron/helloworldrestmicroservice ne pèse que 58.7 MB, car toute la partie Java 8 est déjà présente dans l'image de base java.

  • Vérifions que les dépendances Java (les fichiers Jar) ont correctement été stockées dans les couches de notre image. Exécutez la ligne de commande shell suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
$ docker history mickaelbaron/helloworldrestmicroservice
IMAGE               CREATED             CREATED BY                                      SIZE
c743275a2e56        9 minutes ago       /bin/sh -c #(nop) ENTRYPOINT &{["java" "-cp"    0 B
dc33507001b9        10 minutes ago      /bin/sh -c #(nop) EXPOSE 8080/tcp               0 B
984798af8449        10 minutes ago      mvn package                                     16.67 MB
e2292a741f7b        10 minutes ago      /bin/sh -c #(nop) ADD dir:ae734bc850e38a11ae4   10.52 kB
b6e562a4fae2        10 minutes ago      /bin/sh -c mvn dependency:go-offline --fail-n   32.02 MB
2c8883ca5a35        11 minutes ago      /bin/sh -c #(nop) WORKDIR /work                 0 B
ac47eb4148e6        11 minutes ago      /bin/sh -c #(nop) ADD file:714d5da29e15c08bf3   2.293 kB
2fb225ef5070        11 minutes ago      /bin/sh -c #(nop) ENV MAVEN_HOME=/usr/share/m   0 B
bd2e16436d83        11 minutes ago      /bin/sh -c curl -fsSLk https://archive.apache   10.03 MB
328a3d908308        16 minutes ago      /bin/sh -c #(nop) ENV MAVEN_VERSION=3.3.9       0 B
...

Nous remarquons à ligne 7, l'exécution de notre commande $mvn dependency:go-offline dont le résultat a fait augmenter la taille de l'image de 32 MB. Ceci est dû aux dépendances Java qui ont été téléchargées. Par conséquent, si nous modifions uniquement le code source de notre projet, seule la compilation des sources sera réalisée.

  • Ouvrez la classe fr.mickaelbaron.helloworldrestmicroservice.service et faites une modification (ajoutez par exemple un espace), puis relancez la construction de l'image :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
$ docker build -t mickaelbaron/helloworldrestmicroservice .
...
Step 9 : ADD src /work/src
 ---> 4ba604d49cf8
Removing intermediate container ac52c0fdaf5b
Step 10 : RUN mvn package
 ---> Running in d26528bea4a5
...

Vous noterez que la construction de l'image se fait plus rapidement, car les étapes précédant l'étape 9 sont en cache.

VII. Exercice 5 : Lier les microservices Redis et Rest

VII-A. But

  • Lier deux conteneurs Docker.
  • Définir des variables d'environnement à la création d'un conteneur Docker.
  • Exécuter une commande Linux à partir d'un conteneur Docker en cours.

VII-B. Description

À cette étape nous disposons d'un conteneur correspondant au microservice Redis et d'une image Docker pour le futur microservice helloworldrestmicroservice. Nous allons nous intéresser dans cet exercice à créer le conteneur du microservice helloworldrestmicroservice et lui associer le conteneur du microservice Redis.

VII-C. Étapes à suivre

  • Exécutez la ligne de commande shell suivante :
 
Sélectionnez
1.
$ docker run --name rest -p 8080:8080 -d --link redis:redisalias mickaelbaron/helloworldrestmicroservice

Cette instruction crée un conteneur Docker appelé rest (--name rest), dont le port 8080 est redirigé sur le port 8080 de l'hôte (-p 8080:8080), lancé en tâche de fond (- d), lié au conteneur Redis dont le vhost s'appellera redisalias (--link redis:redisalias) à partir de l'image appelée mickaelbaron/helloworldrestmicroservice.

  • Vérifiez que les deux conteneurs ont été correctement créés :
 
Sélectionnez
1.
2.
3.
4.
$ docker ps
CONTAINER ID        IMAGE                                     COMMAND                  CREATED             STATUS              PORTS                    NAMES
628876a63007        mickaelbaron/helloworldrestmicroservice   "java -cp target/clas"   4 minutes ago       Up 4 minutes        0.0.0.0:8080->8080/tcp   rest
6a5e54214dc3        redis                                     "/entrypoint.sh redis"   23 hours ago        Up 23 hours         6379/tcp                 redis
  • Nous allons vérifier que le conteneur rest a accès au réseau du conteneur redis. Pour cela nous allons exécuter une commande Linux depuis le conteneur rest en cours d'exécution via la commande exec de Docker :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
$ docker exec -it rest /bin/more /etc/hosts
172.17.0.3  628876a63007
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  redisalias 6a5e54214dc3 redis

Vous remarquerez à la dernière ligne que l'alias redisalias est présent. Cela permet au conteneur rest de communiquer avec le conteneur redis.

À chaque création d'une liaison avec l'option --link, Docker crée des variables d'environnement pour obtenir des informations sur le conteneur lié (nom de l'alias, le protocole, l'adresse réseau…).

  • Veuillez afficher ces variables d'environnement en exécutant la commande exec de Docker :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
$ docker exec -it rest /bin/bash -c 'set'
...
PWD=/work
REDISALIAS_ENV_GOSU_VERSION=1.7
REDISALIAS_ENV_REDIS_DOWNLOAD_SHA1=e56b4b7e033ae8dbf311f9191cf6fdf3ae974d1c
REDISALIAS_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.0.7.tar.gz
REDISALIAS_ENV_REDIS_VERSION=3.0.7
REDISALIAS_NAME=/rest/redisalias
REDISALIAS_PORT=tcp://172.17.0.2:6379
REDISALIAS_PORT_6379_TCP=tcp://172.17.0.2:6379
REDISALIAS_PORT_6379_TCP_ADDR=172.17.0.2
REDISALIAS_PORT_6379_TCP_PORT=6379
REDISALIAS_PORT_6379_TCP_PROTO=tcp
...

Vous noterez la variable d'environnement REDISALIAS_PORT qui nous sera utile dans la classe JedisFactory pour se connecter au serveur Redis.

  • Pour vérifier que la connexion fonctionne, vous pouvez exécuter la commande shell Linux suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
$ docker exec -it rest /bin/ping redisalias
PING redisalias (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.372 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.080 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.104 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.105 ms
  • Il nous reste plus qu'à tester le service web contenu dans le conteneur rest :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
# Création d'un HelloWorld à partir d'un contenu JSON
$ curl -H "Content-Type: application/json" -X POST -d '{"message":"Mon HelloWorld"}' http://localhost:8080/helloworld

# Lister les HelloWorld
$ curl http://localhost:8080/helloworld
[{"rid":1,"message":"Mon HelloWorld","startDate":"Sun Jan 31 16:42:35 CET 2016"}]

VIII. Exercice 6 : Émettre et recevoir des événements

VIII-A. But

  • Publier un HelloWorld vers RabbitMQ.
  • Afficher le contenu d'un conteneur Docker.

VIII-B. Description

Nous allons enrichir le projet Java du service web HelloWorld de façon à ce qu'un HelloWorld puisse être publié sur le bus d'événements de RabbitMQ à chaque fois que le service web de création est appelé. Nous allons également créer un nouveau microservice appelé Log (contenu dans le projet helloworldlogmicroservice) qui se chargera de réceptionner les événements envoyés au bus d'événements de RabbitMQ. Pour cela, nous allons utiliser un nouveau projet Java pour l'affichage des logs sur la console.

VIII-C. Étapes à suivre

  • Avant de continuer, nous allons arrêter et supprimer les conteneurs rest et redis. Exécutez les lignes de commande shell suivantes :
 
Sélectionnez
1.
2.
$ docker rm -f rest
$ docker rm -f redis
  • Depuis l'environnement de développement Eclipse, modifiez la classe HelloWorldResource de façon à décommenter les lignes de code relatives à la manipulation d'un objet IHelloWorldEventProducer :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
public class HelloWorldResource {

    @Inject
    @Named("redis")
    private IHelloWorldDAO currentDAO;

    @Inject
    private IHelloWorldEventProducer currentProducer;

    @GET
    public Response getHelloWorlds() {
        return Response.ok(currentDAO.getHelloWorlds()).build();
    }

    @POST
    public Response addHelloWorld(HelloWorld newHelloWorld) {
        if (newHelloWorld != null) {
            newHelloWorld.setStartDate(new Date().toString());
        }

        currentDAO.addHelloWorld(newHelloWorld);
        currentProducer.sendMessage(newHelloWorld);

        return Response.status(Status.CREATED).build();
    }
}
  • Mettez à jour l'image du microservice helloworldrestmicroservice. Placez-vous à la racine du projet helloworldrestmicroservice et exécutez la ligne de commande shell suivante :
 
Sélectionnez
1.
2.
$ docker build -t mickaelbaron/helloworldrestmicroservice .
... // Des tonnes de lignes
  • Importez le projet Maven helloworldlogmicroservice (File -> Import -> General -> Existing Projects into Workspace et choisissez l'option Select root directory puis sélectionnez le répertoire).
  • Examinez la classe HelloWorldLogMicroservice. Les événements reçus sont récupérés et affichés sur la sortie console.
  • Créez un fichier Dockerfile à la racine du projet helloworldlogmicroservice.
  • Ouvrez un éditeur de texte et saisissez le contenu présenté ci-dessous :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
FROM java:openjdk-8-jdk
MAINTAINER Mickael BARON

ENV MAVEN_VERSION 3.3.9
RUN curl -fsSLk https://archive.apache.org/dist/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz | tar xzf - -C /usr/share \
    && mv /usr/share/apache-maven-$MAVEN_VERSION /usr/share/maven \
    && ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
ENV MAVEN_HOME /usr/share/maven

ADD pom.xml /work/pom.xml
WORKDIR /work
RUN ["mvn", "dependency:go-offline"]

ADD ["src", "/work/src"]
RUN ["mvn", "package"]

ENTRYPOINT ["java", "-cp", "target/classes:target/dependency/*", "fr.mickaelbaron.helloworldlogmicroservice.HelloWorldLogMicroservice"]
CMD [localhost]
  • Nous allons construire l'image à partir de fichier Dockerfile, exécutez la ligne de commande shell suivante depuis la racine du projet helloworldlogmicroservice :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
$ docker build -t mickaelbaron/helloworldlogmicroservice .
... // Des tonnes de lignes
Step 6 : ADD pom.xml /work/pom.xml
 ---> cd979cd51636
Removing intermediate container eed894e3b169
...

Vous remarquerez que la construction de l'image commence réellement à partir de l'étape 6. Tout ce qui est avant cette étape est déjà présent dans le cache de Docker.

  • Nous ne pouvons pas continuer tant que le serveur RabbitMQ n'est pas mis en place. Nous allons donc l'installer en l'isolant dans un conteneur. Le microservice résultat s'appellera Rabbitmq. Nous utiliserons une image de RabbitMQ contenant une interface web pour la gestion des événements reçus et envoyés (rabbitmq:management). Exécutez les lignes de commande shell suivantes :
 
Sélectionnez
1.
2.
$ docker pull rabbitmq:management
...

Il ne nous reste plus qu'à créer tous les conteneurs et de faire la liaison comme montrée dans le précédent exercice. Exécutez les lignes de commande shell suivantes :

 
Sélectionnez
1.
2.
3.
4.
$ docker run --name redis -v /var/redis:/data -d redis redis-server --appendonly yes
$ docker run --name rabbitmq -d -p 15672:15672 --hostname my-rabbit rabbitmq:management
$ docker run --name log -d --link rabbitmq:rabbitmqalias mickaelbaron/helloworldlogmicroservice rabbitmqalias
$ docker run --name rest -p 8080:8080 -d --link redis:redisalias --link rabbitmq:rabbitmqalias mickaelbaron/helloworldrestmicroservice
  • Cela fait beaucoup d'instructions, assurons-nous que tous les conteneurs sont opérationnels. Exécutez la ligne de commande shell suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
$ docker ps
CONTAINER ID        IMAGE                                     COMMAND                  CREATED              STATUS              PORTS                          NAMES
f4cf2499ea58        mickaelbaron/helloworldrestmicroservice   "java -cp target/clas"   About a minute ago   Up About a minute   0.0.0.0:8080->8080/tcp         rest
9935fbad7f16        mickaelbaron/helloworldlogmicroservice    "java -cp target/clas"   About a minute ago   Up About a minute                                  log
4f86b1828935        rabbitmq:management                       "/docker-entrypoint.s"   About a minute ago   Up About a minute   ... 0.0.0.0:15672->15672/tcp   rabbitmq
927d55e92592        redis                                     "/entrypoint.sh redis"   2 minutes ago        Up 2 minutes        6379/tcp                       redis
  • Assurons-nous que l'interface d'administration de RabbitMQ fonctionne. Ouvrez un navigateur et saisissez l'adresse http://localhost:15672
Interface de gestion de RabbitMQ
  • Appelez le service web HelloWorld pour tester la chaîne complète des microservices. Exécutez les commandes shell suivantes :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
# Création d'un HelloWorld à partir d'un contenu JSON
$ curl -H "Content-Type: application/json" -X POST -d '{"message":"Mon HelloWorld avec presque tous les microservices"}' http://localhost:8080/helloworld

# Lister les HelloWorld
$ curl http://localhost:8080/helloworld
[{"rid":2,"message":"Mon HelloWorld avec presque tous les microservices","startDate":"Mon Feb 01 16:30:08 UTC 2016"},{"rid":1,"message":"Mon HelloWorld","startDate":"Sun Jan 31 16:42:35 CET 2016"}]
  • Affichez le contenu des logs du conteneur Log en exécutant la commande shell suivante :
 
Sélectionnez
1.
2.
$ docker logs log
[x] Received '{"rid":2,"message":"Mon HelloWorld avec presque tous les microservices","startDate":"Mon Feb 01 16:30:08 UTC 2016"}'

IX. Exercice 7 : Composer tous les microservices avec DockerCompose

IX-A. But

  • Utiliser l'outil Docker Compose pour composer des conteneurs Docker.

IX-B. Description

Précédemment, nous avons procédé à la création de chaque image et nous avons ensuite créé les conteneurs associés. Toutes ces tâches ont été réalisées via les commandes docker pull, docker build et docker run. Comme nous avons pu le constater, cela reste utilisable quand il y a peu de conteneurs, mais lorsqu'il y a plus de deux conteneurs cela devient difficile de tout gérer. C'est pour cette raison que nous allons employer l'outil Docker Compose.

IX-C. Étapes à suivre

  • Avant de commencer, faisons « table rase » en supprimant tous les conteneurs précédemment créés. Exécutez la commande shell suivante :
 
Sélectionnez
1.
$ docker rm -f $(docker ps -q)
  • Assurez-vous que tous les conteneurs ont été supprimés en exécutant la commande shell suivante :
 
Sélectionnez
1.
2.
3.
$ docker ps -a
Name   Command   State   Ports
------------------------------

Nous allons également introduire un nouveau microservice qui se chargera de fournir une interface web à notre application. Le code de cette application est dans le projet helloworldwebmicroservice. Le contenu du code est réalisé en HTML, JavaScript, Bootstrap et JQuery. Les dépendances des bibliothèques JavaScript sont gérées par l'outil Bower et la version distribuable du projet est obtenue par des tâches Grunt.

  • Parcourez les fichiers contenus dans le projet helloworldwebmicroservice. Vous remarquerez dans le fichier resthosts.js une variable restHostUrl qui prend la valeur de l'URL du microservice Rest. Dans notre cas, il s'agit de l'URL http://localhost:8080/helloworld. Modifiez la valeur de cette variable.
  • Créez un fichier docker-compose.yml à la racine du répertoire helloworldmicroservices.
  • Éditez le fichier et complétez-le comme ci-dessous :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
redis:
  image: redis
  volumes:
    - /var/redis:/data
  command: redis-server --appendonly yes

rabbitmq:
  image: rabbitmq:management
  hostname: my-rabbit
  ports:
    - 5672:5672
    - 15672:15672

rest:
  build: helloworldrestmicroservice/
  links:
    - rabbitmq:rabbitmqalias
    - redis:redisalias
  ports:
    - 8080:8080

web:
  build: helloworldwebmicroservice
  ports:
    - 80:8080

log:
  build: helloworldlogmicroservice/
  links:
    - rabbitmq:rabbitmqalias
  command: rabbitmqalias

Veuillez noter que nous retrouvons toutes les options passées en paramètres des commandes docker run… des exercices précédents.

  • Nous pouvons donc exécuter ce fichier en utilisant la commande docker-compose up comme précisé ci-dessous :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
$ docker-compose up -d
Building web
Step 1 : FROM node:latest
latest: Pulling from library/node
...
Removing intermediate container feca0f353d33
Successfully built e8c7b787adc4
Creating microservices_log_1
  • Affichez les logs des conteneurs en exécutant la commande suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
$ docker-compose logs
...
redis_1    | 1:M 03 Feb 18:32:23.099 * The server is now ready to accept connections on port 6379
web_1      | Starting up http-server, serving /workdir/site
web_1      | Available on:
web_1      |   http:127.0.0.1:8080
web_1      | Hit CTRL-C to stop the server

Pour différencier de quelle sortie les logs sont issus, il est précisé sur la zone de gauche le nom du conteneur en suivant la nomination _. précise le nom du conteneur et précise de quelle instance du conteneur il s'agit. Cette information est importante quand vous faites usage de docker-compose scale pour augmenter le nombre d'instances d'un conteneur. Nous étudierons ce point dans un prochain tutoriel.

  • Vérifiez que tous les conteneurs ont été correctement créés en exécutant la ligne commande suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
$ docker-compose ps
          Name                        Command               State                                             Ports
--------------------------------------------------------------------------------------------------------------------------------------------------------------
microservices_log_1        java -cp target/classes:ta ...   Exit 1
microservices_rabbitmq_1   /docker-entrypoint.sh rabb ...   Up      15671/tcp, 0.0.0.0:15672->15672/tcp, 25672/tcp, 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp
microservices_redis_1      /entrypoint.sh redis-serve ...   Up      6379/tcp
microservices_rest_1       java -cp target/classes:ta ...   Up      0.0.0.0:8080->8080/tcp
microservices_web_1        http-server /workdir/site  ...   Up      0.0.0.0:80->8080/tcp

Nous remarquons que le conteneur microservices_log_1 est arrêté (State = Exit 1).

  • Examinons les logs du conteneur du microservice Log pour comprendre la raison de son arrêt. Veuillez exécuter la ligne de commande suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
$ docker logs microservices_log_1
Exception in thread "main" java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at com.rabbitmq.client.impl.FrameHandlerFactory.create(FrameHandlerFactory.java:32)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:676)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:722)
    at fr.mickaelbaron.helloworldlogmicroservice.HelloWorldLogMicroservice.<init>(HelloWorldLogMicroservice.java:26)
    at fr.mickaelbaron.helloworldlogmicroservice.HelloWorldLogMicroservice.main(HelloWorldLogMicroservice.java:72)

Le programme Java qui traite les logs n'arrive pas à se connecter au serveur RabbitMQ puisque ce dernier a un temps de démarrage relativement long. Par conséquent la connexion au serveur RabbitMQ est faite trop tôt. Cette problématique est connue chez les utilisateurs de l'outil Docker Compose https://docs.docker.com/compose/faq/#how-do-i-get-compose-to-wait-for-my-database-to-be-ready-before-starting-my-application. Pour pallier ce problème, nous allons modifier le programme Java afin de pouvoir tenter une nouvelle connexion en cas d'échec. Cette solution est connue sous le nom de healthcheck.

  • Ouvrez et éditez la classe fr.mickaelbaron.helloworldlogmicroserviceHelloWorldLogMicroservice et ajoutez le code suivant :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
    public HelloWorldLogMicroservice(String rabbitMQHosts) ... {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(rabbitMQHosts);

        final Connection connection = createConnection(factory);
        final Channel channel = connection.createChannel();
        ...
    }

    private Connection createConnection(ConnectionFactory factory) ... {
        // We implement an healthcheck.

        boolean connectionIsReady = false;
        Connection connection = null;
        while(!connectionIsReady) {
            try {
                connection = factory.newConnection();
                connectionIsReady = true;
            } catch (Exception e) {
                System.out.println("Problem:" + e.getMessage());
                System.out.println("We will try to connect to RabbitMQ in 5s.");
                Thread.sleep(5000);
            }
        }

        System.out.println("Great !! Connected to RabbitMQ.");

        return connection;
    }
  • Pour recompiler, exécutez la ligne de commande shell suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
$ docker-compose build
...
Step 10 : RUN mvn package
 ---> Running in b6f785413e68
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building helloworldlogmicroservice 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
...
  • Pour relancer, le conteneur (et si besoin les conteneurs qui en dépendraient), exécutez la ligne de commande shell suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
$ docker-compose up -d
microservices_web_1 is up-to-date
microservices_redis_1 is up-to-date
microservices_rabbitmq_1 is up-to-date
microservices_rest_1 is up-to-date
Recreating microservices_log_1
  • Vérifiez que les conteneurs ont correctement été créés en exécutant la ligne de commande shell suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
$ docker-compose ps
          Name                        Command               State                                             Ports
--------------------------------------------------------------------------------------------------------------------------------------------------------------
microservices_log_1        java -cp target/classes:ta ...   Up
microservices_rabbitmq_1   /docker-entrypoint.sh rabb ...   Up      15671/tcp, 0.0.0.0:15672->15672/tcp, 25672/tcp, 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp
microservices_redis_1      /entrypoint.sh redis-serve ...   Up      6379/tcp
microservices_rest_1       java -cp target/classes:ta ...   Up      0.0.0.0:8080->8080/tcp
microservices_web_1        http-server /workdir/site  ...   Up      0.0.0.0:80->8080/tcp
  • Il ne nous reste plus qu'à tester. Ouvrez un navigateur et rendez-vous à cette adresse : http://localhost.
Interface web de l'application HelloWorld

X. Conclusion, perspectives et remerciements

Nous avons vu au travers de huit exercices comment construire une application en respectant une architecture à base de microservices. Nous avons utilisé un ensemble de technologies dont notamment Docker pour l'isolation, RabbitMQ pour la communication asynchrone via un bus d'événements, Docker Compose pour la composition et des services web REST pour la communication synchrone.

La solution complète de cette série d'exercices est disponible en téléchargement : helloworldmicroservices-sol.zip. ou directement sur mon Github : https://github.com/mickaelbaron/helloworldmicroservices

Dans un prochain atelier, nous montrerons les aspects de montée en charge et notamment l'avantage d'utiliser Docker Compose pour le pilotage du nombre de conteneurs d'une même image. Nous insisterons aussi sur l'intérêt d'utiliser un reverse proxy et un load balancer dans ce cas d'usage.

Pour aller plus loin, vous pouvez consulter les ressources suivantes :

Je tiens à remercier Claude Leloup pour la relecture orthographique de cet article et Logan Mauzaize pour sa relecture technique attentive et ses nombreuses bonnes pratiques.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2016 Mickael Baron. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.