L’université de la performance vous fera découvrir comment concevoir la plus grosse fonctionnalité implicite d’une application: Sa performance.
Pour cela nous vous proposerons une démarche en trois étapes: - Connaître les différents types de tests de charge et savoir quand les utiliser - Mettre en place un test de charge et des outils nécessaires pour le monitoring - Savoir identifier et optimiser les différents goulets d’étranglement de l’application
Le tout mis en pratique sur une application réelle.
11. 111
1
Les performances d’un
système sont une
spécification
fonctionnelle implicite
du système
Notre vision ?
Source : www.arthursclipart.org
12. 121
2
La mesure de performance
doit être au coeur du
processus de
développement
informatique
Notre vision ?
Source : Les géants du Web
13. LES 4 DIFFÉRENTS TYPES DE TEST
131
3
• Objectif : mesurer la performance unitaire
• Ex : le use case de souscription est testé pour 1 utilisateur
et, pour chaque étape du use case, on mesure le temps
passé dans les différents composants de l’application
Test de
performance
unitaire
• Objectif : mesurer la tenue en charge de l’application sur la
population cible
• Ex : on simule l’utilisation de l’application par 200
utilisateurs en parallèle pendant 2h
Test de
charge
• Objectif : déterminer les limites de l’application
• Ex : on augmente le nombre d’utilisateurs en parallèle sur
l’application jusqu’à ce que le taux d’erreurs / les temps de
réponse ne soient plus acceptables
Test de
rupture
• Objectif : déterminer la capacité de l’application à
fonctionner sur une période étendue
• Ex : on simule l’utilisation de l’application pendant 48h,
avec une charge constante et égale à la charge moyenne
Test de
vieillissement
14. 141
4
La démarche de test que nous utilisons
Global vers Local puis Local vers Global
TESTS DE CHARGE
TESTS DE PERFORMANCE
UNITAIRE
Mesurer Optimiser
15. 151
5
La démarche de test que nous utilisons
TESTS DE CHARGE
TESTS DE PERFORMANCE
UNITAIRE
Mesurer Optimiser
Scénarios
+
Monitoring
Exécution
des
scénarios
Optimisations
Estimation gains
potentiels
• Environnements de
production
• Scénarios
représentatifs
• Jeux de données
• Cible à atteindre
• Simulation
• (Correction)
• Mesure
• Investigations
• Sur un poste de
développement
• Validation des
hypothèses
• Tuning des « hot
spots »
16. 161
6
Définition du plan et des
cas de test
Méthodologie d’un test de charge
Plan de test Cas de test
Création des scénarii et
des scripts de tests
Enregistrement des
métriques
Consolidation des
métriques et édition
d’un rapport de test
Métriques
Rapport de test
Analyse du rapport de
test et émission des
préconisations Rapport d’analyse
Contrôleur
Scripts
de test
Scénarii
de test
Application
à tester
Injecteurs
Données
de test
Création des jeux de
données
1
2
3
3
Monitoring
3 Exécution
4
5
2
17. 171
7
Les outils utilisés aujourd’hui
GÉNÉRER LES DONNÉES
! Migrer les données depuis la production mais
il faut souvent l’anonymiser.
! Générer un jeux de données mais il doit être
représentatif
! Rétablir le jeux de données dans son état
initial une fois le tir effectué
TESTER EN CHARGE
! Enregistrer et rejouer de manière fidèle un
ensemble d’actions utilisateurs.
! Variabiliser ces actions utilisateurs pour être
représentatif de l’usage réel
! Simuler un grand nombre d’utilisateurs
MONITORER LA CONSOMMATION DE
RESSOURCES
! Identifier les ressources en quantité limitante
! Identifier les impacts sur les différentes
machines lorsque l’application est distribuée
! Corréler l’évolution des temps de réponse et
les consommations de ressources sur les
différentes machines
18. 181
8
Les outils en général
HPJMeter
Analyse de log GC
Injection
Profiling
APM
19. 191
9
Notre fil rouge : Happy Store
Navigateur Tomcat PgSQL
Une application comme on en
rencontre souvent, pas très loin de
l’état de l’art.. Sauf pour les
performances !
20. 202
0
Architecture
APPLICATION SERVER
DATABASE SERVER
Tomcat
JVM
PostgreSQL
21. 212
1
Modèle de base de données
Store
0,n
1
Stock
Category Family Product Sales Operation
VAT Country Sales Transaction
1 0,n
0,n
0,n
0,n 1
0,n 1
0,n 1
1
1,n
1
0,n
24. 242
4
Calcul de l’inventaire sur un magasin
Inventory
25. 252
5
Calcul du chiffre d’affaire par groupe de produits
Turnover
(group by+order by)
26. 262
6
Cible de performance
! Cible : 100 utilisateurs concurrents
! Volumétrie de la base de données : 13 millions de lignes
Store
0,n
1
Stock
10'000'000
1'000 1'000
Category Family Product Sales Operation
VAT Country Sales Transaction
1 0,n
0,n
0,n
0,n 1
0,n 1
0,n 1
1
1,n
1
0,n
260
1'000
10'000
3'000'000
0
27. LES DIFFÉRENTS TYPES DE TEST
272
7
• Objectif : mesurer la performance unitaire
• Ex : le use case de souscription est testé pour 1 utilisateur
et, pour chaque étape du use case, on mesure le temps
passé dans les différents composants de l’application
Test de
performance
unitaire
• Objectif : mesurer la tenue en charge de l’application sur la
population cible
• Ex : on simule l’utilisation de l’application par 200
utilisateurs en parallèle pendant 2h
Test de
charge
• Objectif : déterminer les limites de l’application
• Ex : on augmente le nombre d’utilisateurs en parallèle sur
l’application jusqu’à ce que le taux d’erreurs / les temps de
réponse ne soient plus acceptables
Test de
rupture
• Objectif : déterminer la capacité de l’application à
fonctionner sur une période étendue
• Ex : on simule l’utilisation de l’application pendant 48h,
avec une charge constante et égale à la charge moyenne
Test de
vieillissement
29. 292
9
Que fais le serveur applicatif pendant ce temps ?
! Identifier la JVM
! Faire un threadump pendant la requête
30. 303
0
! C’est le seul à exécuter du code applicatif
Identifier notre Thread
! Il attend la base… mais quelle est la requête ?
31. 313
1
! Vérification de la configuration des traces
! Les requêtes de plus de 700ms sont tracées
! On obtient la requête et ses paramètres d’appel
Allons voir la DB
32. 323
2
Pourquoi cette requête est lente ?
select sum(amount), ….
from SaleOperation
where groupId=1 and operationdate >= '2010-04-15 00:21:31.529'
group by saleoperation.currency
order by sum(saleoperation.amount) desc;
! Demandons au moteur du SGBD…
! Un index pourrait aider à mieux filtrer les lignes…
34. 343
4
Remplissage des données : Benerator
! Principes : la base de données est alimentées avec 2 sources
! Une (petite) partie des données est maitrisée
! Généralement le jeux de données utilisés pour les tests d’intégration
! Cohérent avec les scripts d’injection (permet de faire des assertions)
! Une (grosse) partie des données est générée aléatoirement
xxx
xxx
Store
0,n
1
Stock
10'000'000
4
16
4 4
1'000 1'000
Category Family Product Sales Operation
VAT Country Sales Transaction
1 0,n
0,n
0,n
0,n 1
0,n 1
0,n 1
1
1,n
1
0,n
260
1'000
10'000
3'000'000
0
260 256
1
2
36. 363
6
! Temps de création de happystore è 1h20
! 8 tables / 13 M de lignes
! (un thread sur MB avec VM)
! Temps de rechargement è 25 min
Temps de génération
37. LES DIFFÉRENTS TYPES DE TEST
383
8
• Objectif : mesurer la performance unitaire
• Ex : le use case de souscription est testé pour 1 utilisateur
et, pour chaque étape du use case, on mesure le temps
passé dans les différents composants de l’application
Test de
performance
unitaire
• Objectif : mesurer la tenue en charge de l’application sur la
population cible
• Ex : on simule l’utilisation de l’application par 200
utilisateurs en parallèle pendant 2h
Test de
charge
• Objectif : déterminer les limites de l’application
• Ex : on augmente le nombre d’utilisateurs en parallèle sur
l’application jusqu’à ce que le taux d’erreurs / les temps de
réponse ne soient plus acceptables
Test de
rupture
• Objectif : déterminer la capacité de l’application à
fonctionner sur une période étendue
• Ex : on simule l’utilisation de l’application pendant 48h,
avec une charge constante et égale à la charge moyenne
Test de
vieillissement
38. 393
9
Architecture
LOCAL SERVER APPLICATION SERVER
DATABASE SERVER
Gatling
Tomcat
JVM
PostgreSQL
45. 474
7
Premature optimization is the
root of all evil - Donald Knuth
46. 484
8
Il voulait dire ça:
// Do not use the for(Object o : list)
// because I think it is probably
// slower than doing this… Probably…
for(int i = 0; i < list.size(); i++) {
Object o = list.get(i);
…
}
Stop guessing damn it!!!
47. 494
9
Code
Mesure
Optimise Là où
c’est
important
54. 565
6
3. Développement
2. Automatisation
Architecture Développement
Perf.
1. Conception
des tests
des tests
logiciel
4. Exécution auto-matique
des tests
#1 #2 #3
55. 575
7
3. Développement
2. Automatisation
des tests
#1 #2 #3
Délai
Perf.
PERFORMANCES
CATASTROPHIQUES
MEP À L’ARRACHE
logiciel
4. Exécution auto-matique
des tests
1. Conception
des tests
Développement
Architecture
Résultats
Production
56. 585
8
3. Développement
2. Automatisation
1. Conception
des tests
des tests
logiciel
4. Exécution auto-matique
des tests
#1 #2 #3
Architecture
Développement Production
Tests de charge en continue
57. 595
9
Intégrer les tests de performances au cycle de
développement?
Hyperviseur
AppServer
Chef
DbServer
Chef
1
2
3
Créer environnement
Tir de performance
Destruction environnement
59. LES DIFFÉRENTS TYPES DE TEST
636
3
• Objectif : mesurer la performance unitaire
• Ex : le use case de souscription est testé pour 1 utilisateur
et, pour chaque étape du use case, on mesure le temps
passé dans les différents composants de l’application
Test de
performance
unitaire
• Objectif : mesurer la tenue en charge de l’application sur la
population cible
• Ex : on simule l’utilisation de l’application par 200
utilisateurs en parallèle pendant 2h
Test de
charge
• Objectif : déterminer les limites de l’application
• Ex : on augmente le nombre d’utilisateurs en parallèle sur
l’application jusqu’à ce que le taux d’erreurs / les temps de
réponse ne soient plus acceptables
Test de
rupture
• Objectif : déterminer la capacité de l’application à
fonctionner sur une période étendue
• Ex : on simule l’utilisation de l’application pendant 48h,
avec une charge constante et égale à la charge moyenne
Test de
vieillissement
60. 646
4
Test de rupture
100
requêtes par secondes
nombre d'utilisateurs
61. 656
5
Montée en charge
nombre d'utilisateurs
durée
2h 0 min
delay ramp up duration
62. 666
6
Montée en charge et retour à la normal
nombre d'utilisateurs
durée
delay ramp up duration
66. LES DIFFÉRENTS TYPES DE TEST
707
0
• Objectif : mesurer la performance unitaire
• Ex : le use case de souscription est testé pour 1 utilisateur
et, pour chaque étape du use case, on mesure le temps
passé dans les différents composants de l’application
Test de
performance
unitaire
• Objectif : mesurer la tenue en charge de l’application sur la
population cible
• Ex : on simule l’utilisation de l’application par 200
utilisateurs en parallèle pendant 2h
Test de
charge
• Objectif : déterminer les limites de l’application
• Ex : on augmente le nombre d’utilisateurs en parallèle sur
l’application jusqu’à ce que le taux d’erreurs / les temps de
réponse ne soient plus acceptables
Test de
rupture
• Objectif : déterminer la capacité de l’application à
fonctionner sur une période étendue
• Ex : on simule l’utilisation de l’application pendant 48h,
avec une charge constante et égale à la charge moyenne
Test de
vieillissement
67. 717
1
! Déterminer la capacité de l’application à fonctionner sur une
période étendue
! Durant ce tests on va surveiller les dérives au cours du temps :
! Temps de réponse
! Consommation de ressource (espace disk, CPU, mémoire, etc.)
! Libération des ressources (connexions, file, etc.)
! Mémoire
Objectif
68. 727
2
Montée en charge
nombre d'utilisateurs
durée
20 min 24h
delay ramp up duration
70. 747
4
Memory Leak [1/3]
! Analyse des logs GC avec HPJMeter (ou Censum)
! -Xloggc:gc.log -XX:+PrintTenuringDistribution -XX:+PrintGCDetails
71. 757
5
! Heapdump puis Eclipse Memory Analyzer (statique)
! Rapport sur les suspects
Memory Leak [2/3]
72. 767
6
! Visual VM (dynamique)
Memory Leak [3/3]
! On cherche les objets vivants avec un grand nombre de génération
! Jdk 8+ pour les JVM remote
73. 777
7
Résumé de la session
Préparer les jeux de données Benerator
Exécuter une mesure unitaire Chrome developer tools
Identifier un problème d’index jstack, explain plan
Exécuter des tests de charge Gatling
Automatisation des tests de
charge
Jenkins, Capistrano, Chef
Problème de contention VisualVM, jstack
Mise en place du monitoring Metrics, collectd et Graphite
Identifier une fuite mémoire VisualVM, EMA, HPJMeter
Tuning système Bonnie++
74. 787
8
! Tunning Système
! Exemple Bonnie++
Pour aller plus loin
75. 808
0
! La conférence originale à Devoxx FR 2014 :
https://parleys.com/play/536749d1e4b04bb59f502709
! Exemple de benchmark:
http://blog.octo.com/lart-du-benchmark/
! Conférence sur l’industrialisation (USI 2013):
https://www.youtube.com/watch?v=BXO3LYQ9Vic
! Tests de performance SQLFire:
http://blog.octo.com/en/sqlfire-from-the-trenches/
Liens utiles
76. 818
1
! Remerciement à Henri Tremblay, Marc Bojoly, Mickaël Robert & Ludovic Piot