TP étude de performances
1. Objectif
L’objectif de ce TP est de vous faire travailler sur deux études de performances :
-
TP vert : la comparaison de performances entre REST, gRPC et GraphQL
-
TP bleu : l’étude de performance d’un load balancer
Votre travail sur ce TP sera à intégrer dans votre rapport. J’attends aussi un rendu de code pour ce TP. Attention la séance va passer vite !
2. TP vert - Comparaison de performances REST/gRPC/GraphQL
2.1. Tests de performances
Vous avez déjà codé vos TP avec différentes API : REST, gRPC, et GraphQL. L’idée ici est de venir vérifier nos attentes en termes de performances entre REST, gRPC et GraphQL. Pour cela vous allez devoir réfléchir à des benchmarks permettant de tester et comparer les performances de chaque solution de façon équitable et juste.
Je vous rappelle par exemple que :
-
gRPC est sensé être plus efficace que REST et GraphQL car il utilise HTTP/2 mais comment le vérifier et à partir de quelle taille de requête/réponse cela est vrai ?
-
GraphQL est plus difficile à mettre en cache que REST en toute logique, comment vérifier cette baisse de performance potentielle ?
-
Si un client n’a besoin que d’une partie de l’information, GraphQL doit avoir de meilleures performances que REST, comment le vérifier ?
-
etc.
Vous pouvez imaginer toute sorte de comparaisons pour mener à bien ces tests, par exemple :
-
comparaison avec différentes requêtes GET, POST
-
comparaison avec des requêtes plus ou moins lourdes
-
comparaison face à un grand nombre de requêtes
Tip
|
vous pouvez créer pour ces tests de performances des services jouets dont le but est de mettre à l’épreuve les différentes solutions (retour de requête très lourd etc.). Vous pouvez cependant commencer par tester des services écrits pour nos TP précédents. |
Important
|
pour faire un grand nombre de requêtes par seconde vous pouvez utiliser une bibliothèque qui fera des requêtes asynchrones comme par exemple (mais sans doute d’autres) https://github.com/spyoungtech/grequests |
2.2. Rendus
Je vous demande de :
-
concevoir des scripts
Python
(ou un autre langage) pour ces tests de performance -
me faire un rendu de vos codes avec les instructions pour rejouer vos tests (un déploiement Docker sera plus simple pour moi)
-
un petit descriptif dans le rapport de la mise en place de vos tests et de l’analyse de vos résultats
3. TP bleu - Etude de performance de NGINX
L’objectif de ce tutoriel est de déployer au moyen de conteneurs Docker
plusieurs instances de notre service Movie
et de configurer et déployer
Nginx
qui va nous permettre de répartir les requêtes entre les différentes
instances de Movie
. Vous allez ensuite coder un script de pour tester les performances
de la solution mise en place.
Vous pouvez utiliser votre service Movie REST dans ce TP.
3.1. Conteneur pour le service Nginx
Clonez ou téléchargez le zip du repo GitHub suivant : https://github.com/IMTA-LOGIN/tp-perfs
Nous n’allons pas rentrer dans le détail de la configuration de nginx
ici
mais vous pouvez jeter un oeil au fichier nginx.conf
dans lequel sont
précisées les adresses des services pour lesquels nous allons faire un load
balancing. Comprenez pour le moment que nous aurons 4 instances du service movie
. Notez aussi
que notre service nginx
écoute le port 8000
.
Voici le contenu du fichier Dockerfile
pour le service nginx
FROM nginx
WORKDIR /app
ADD ./nginx.conf /app/
ADD ./nginx-default-container.conf /etc/nginx/nginx.conf
Notez que pour construire le conteneur nous utilisons l’image de base nginx
disponible sur Docker Hub ce qui nous permet de ne pas nous soucier de
l’installation de nginx
nous même : https://hub.docker.com/_/nginx/
Nous créons ici encore le répertoire de travail de notre conteneur /app
dans lequel est copié le fichier nginx.conf
. Le fichier
nginx-default-container.conf
est quand à lui copié à la place du fichier de
configuration de base dans /etc/nginx
sur le conteneur.
3.2. Déploiement de nos conteneurs
Voici maintenant le contenu du fichier docker-compose.yaml
mis à jour :
version: "3.9"
services:
movie1:
build: ./movie/
ports:
- "5001:5001"
movie2:
build: ./movie/
ports:
- "5002:5001"
movie3:
build: ./movie/
ports:
- "5003:5001"
movie4:
build: ./movie/
ports:
- "5004:5001"
nginx:
build: ./nginx/
ports:
- "8000:8000"
Les différentes instances de notre service movie
sont nommées movie1
movie2
movie3
et
movie4
. Toutes ces instances fonctionnent en interne sur
le port 5001 et nous précisons donc une association de ports pour interroger
nos conteneurs sans conflits 5001
5002
5003
et 5004
. Notre service
nginx
quand à lui écoute le port 8000
qui est conservé aussi pour le
conteneur.
Une chose très importante est que Docker compose
gère un serveur de noms qui
permet aux conteneurs de se connaître les uns les autres. Ainsi le service
nginx
connait les services movie1`etc. C’est pour cette raison que nous
avons ces adresses dans le fichier `nginx.conf
:
upstream loadbalancer{
server movie1:5001;
server movie2:5001;
server movie3:5001;
server movie4:5001;
}
Reconstruisons notre déploiement avec la commande
docker-compose build
Puis lançons le déploiement
docker-compose up
Vous deviez voir tous les services se lancer de cette façon :
Creating seance5_movie4_1 ... done
Creating seance5_nginx_1 ... done
Creating seance5_movie3_1 ... done
Creating seance5_movie1_1 ... done
Creating seance5_movie2_1 ... done
Attaching to seance5_movie4_1, seance5_movie2_1, seance5_movie1_1, seance5_nginx_1, seance5_movie3_1
nginx_1 | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx_1 | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
movie4_1 | Server running in port 5001
movie4_1 | * Serving Flask app 'movie' (lazy loading)
movie4_1 | * Environment: production
movie4_1 | WARNING: This is a development server. Do not use it in a production deployment.
movie4_1 | Use a production WSGI server instead.
movie4_1 | * Debug mode: off
movie4_1 | * Running on all addresses.
movie4_1 | WARNING: This is a development server. Do not use it in a production deployment.
movie4_1 | * Running on http://172.19.0.2:5001/ (Press CTRL+C to quit)
nginx_1 | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
nginx_1 | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
nginx_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
nginx_1 | /docker-entrypoint.sh: Configuration complete; ready for start up
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: using the "epoll" event method
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: nginx/1.21.4
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: OS: Linux 5.4.0-92-generic
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: start worker processes
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: start worker process 31
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: start worker process 32
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: start worker process 33
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: start worker process 34
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: start worker process 35
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: start worker process 36
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: start worker process 37
nginx_1 | 2022/01/09 11:18:06 [notice] 1#1: start worker process 38
movie2_1 | Server running in port 5001
movie2_1 | * Serving Flask app 'movie' (lazy loading)
movie2_1 | * Environment: production
movie2_1 | WARNING: This is a development server. Do not use it in a production deployment.
movie2_1 | Use a production WSGI server instead.
movie2_1 | * Debug mode: off
movie2_1 | * Running on all addresses.
movie2_1 | WARNING: This is a development server. Do not use it in a production deployment.
movie2_1 | * Running on http://172.19.0.3:5001/ (Press CTRL+C to quit)
movie3_1 | Server running in port 5001
movie3_1 | * Serving Flask app 'movie' (lazy loading)
movie3_1 | * Environment: production
movie3_1 | WARNING: This is a development server. Do not use it in a production deployment.
movie3_1 | Use a production WSGI server instead.
movie3_1 | * Debug mode: off
movie3_1 | * Running on all addresses.
movie3_1 | WARNING: This is a development server. Do not use it in a production deployment.
movie3_1 | * Running on http://172.19.0.6:5001/ (Press CTRL+C to quit)
movie1_1 | Server running in port 5001
movie1_1 | * Serving Flask app 'movie' (lazy loading)
movie1_1 | * Environment: production
movie1_1 | WARNING: This is a development server. Do not use it in a production deployment.
movie1_1 | Use a production WSGI server instead.
movie1_1 | * Debug mode: off
movie1_1 | * Running on all addresses.
movie1_1 | WARNING: This is a development server. Do not use it in a production deployment.
movie1_1 | * Running on http://172.19.0.4:5001/ (Press CTRL+C to quit)
Le téléchargement des images de base depuis Docker Hub
peut prendre un peu
de temps, c’est normal, mais une fois téléchargé vous n’aurez plus à le
refaire.
Vous pouvez tester le fonctionnement de vos services movie
avec les url
suivantes dans votre navigateur :
http://localhost:5001/json
http://localhost:5002/json
http://localhost:5003/json
http://localhost:5004/json
http://localhost:8000/json
Les 3 premières requêtes vont partir vers les services movie
dans les conteneurs qui exposent leurs ports respectifs
5001, 5002, 5003, et 5004. La dernière requête part vers nginx
qui relaye la requête à l’un des 4 services dans
les conteneurs.
3.3. Tests de performances
C’est maintenant à vous de jouer ! Le but de ce TP est d’étudier les performances de NGINX.
Vous pouvez laisser libre cours à votre imagination pour écrire des scripts Python
(ou autre)
qui mettent à l’épreuve le load balancing.
Vous pouvez :
-
faire des courbes en fonction du nombre de services
Movie
disponibles et du nombre de requêtes par seconde -
comprendre les différentes configurations possibles de NGINX et les tester (https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/)
Tip
|
pour faire un grand nombre de requêtes par seconde vous pouvez utiliser une bibliothèque qui fera des requêtes asynchrones comme par exemple (mais sans doute d’autres) https://github.com/spyoungtech/grequests |
3.4. Rendus
Je vous demande de :
-
concevoir des scripts
Python
(ou un autre langage) pour ces tests de performance -
me faire un rendu de vos codes avec les instructions pour rejouer vos tests
-
un petit descriptif dans le rapport de la mise en place de vos tests et de l’analyse de vos résultats