3. Antonio Gomes Rodrigues
● Consultant en performances JavaEE
● Plus de 6 ans d'expériences
● Rédacteur sur developpez.com
● http://arodrigues.developpez.com/
4. Des ressources Des actualités
http://twitter.com/javaDeveloppez
java@redaction-developpez.com
De l'entraide Un hébergement gratuit
w w
:/ /w
http
6. Commencez par faire correctement les choses,
puis accélérez-les si cela ne va pas assez vite
7. Sommaire
● Procédure de test
● Définition de la stratégie de test
● Faire un test de charge
● Identifier les problèmes
● Diagnostic Java EE
8. Sommaire
● Procédure de test
● Définition de la stratégie de test
● Faire un test de charge
● Identifier les problèmes
● Diagnostic Java EE
9. Procédure de test
● Itératif
● Préparer les tests
● Mesurer les performances
● Identifier les problèmes
● Corriger les problèmes (faire seulement une
modification à la fois)
● Recommencer jusqu'à atteindre les objectifs
10. Sommaire
● Procédure de test
● Définition de la stratégie de test
● Faire un test de charge
● Identifier les problèmes
● Diagnostic Java EE
13. Définir les objectifs de l'audit de
performance
● Résoudre des problèmes de performance d'une
application,
● Dimensionner une infrastructure de production pour un
déploiement national,
● Rassurer la DSI sur la montée en charge d'une
application
● Valider les performances/endurance/robustesse d'une
application,
● Comparer des solutions,
● ...
14. Identifier les scénarios pertinents et
les pondérer
● Des scénarios réalistes (écrans consultés, champs
saisis dans les formulaires, temps entre chaque
actions, ...).
● Faire les scénarios importants (ceux de tous les jours
mais aussi ceux importants d'un point de vue
fonctionnel (déclenchement de la paye, ...))
● Voir les logs d'accès, cas d'utilisation, ...
● Attention au cas où l'application fait appel à un service
extérieur (serveur de cartographie, serveur de
validation du numéro de carte bleue, ...).
15. Identifier les outils et les ressources
à disposition
● Outils mis à disposition (LoadRunner, JMeter,
Introscope, ...)
● Disponibilité des développeurs, fonctionnels, DBA,
administrateur système, ...
● S'assurer de la disponibilité exclusive de
l'environnement
16. S'assurer que la plateforme testée
est la plus proche possible de la
plateforme cible
17. S'assurer que la plateforme de test
répond aux exigences du test
18. S'assurer d'avoir un jeux de
données réaliste
● Données de prod, ETL, Outils spécifique
(Benerator, ...)
19. Démo de Benerator
● Plugin pour Maven2
● Plugin pour Eclipse
● Personnalisable
● Gratuit
● Bonne documentation
● Supporte la majorité des bases de données du
marché
● http://databene.org/databene-benerator
22. Sommaire
● Procédure de test
● Définition de la stratégie de test
● Faire un test de charge
● Quand faire un test de charge
● Quoi mesurer/vérifier
● Quand donner les résultats
● Que va t-on trouver
● Process
● Rapport d'audit
23. Sommaire
● Procédure de test
● Définition de la stratégie de test
● Faire un test de charge
● Quand faire un test de charge
● Quoi mesurer/vérifier
● Quand donner les résultats
● Que va t on trouver
● Procédure
● Rapport d'audit
25. Demo de ContiPerf
● Simple d'utilisation
● Intégration à Maven2
● Intégration à Eclipse
● Export des résultats au format CSV
● …
● http://databene.org/contiperf.html
26. Demo de Yourkit Java Profiler
● Une grande richesse fonctionnelle
● Intégration aux principaux IDE du marché
● Multi plate-forme
● Intégration aux principaux serveurs
d'application
● Contrôle de l'overhead pour s'adapter à la
machine cible
● http://www.yourkit.com/overview/index.jsp
27. Quand faire un test de charge
● En fin de projet
● Pour :
● Régler les serveurs
● Augmenter les performances
● Valider la mise en production,
● ...
28. Sommaire
● Procédure de test
● Définition de la stratégie de test
● Faire un test de charge
● Quand faire un test de charge
● Quoi mesurer/vérifier
● Quand donner les résultats
● Que va t-on trouver
● Procédure
● Rapport d'audit
30. Sur chaque serveur
● L’activité du système
● L’activité du réseau (débit, taux de perte, ...)
● L’occupation mémoire (mémoire occupée,
mémoire libre, mémoire swap, ...)
● L’occupation du processeur (taux
d'occupation, ...)
31. Sur chaque JVM
● JVM Mode
● Vérifier qu'on est bien en "-server"et non en "-client" (En
particulier sur les JVM 1.4 et inférieur)
● Taille de la Java Heap
● La taille de la heap (Java options -Xmx (maximum) et
-Xms (minimum)) et son comportement.
● Comportement du Garbage Collection
● Sa fréquence, son temps d'exécution, ... (-verbose:gc,
-XX:+PrintGCTimeStamps, -XX:+PrintGCDetails)
● Dump mémoire
● -XX:+HeapDumpOnOutOfMemoryError
● -XX:+HeapDumpOnCtrlBreak
32. Sur les serveurs d'application
● L’activité du système
● L’activité du réseau (débit, taux de perte, ...)
● L’occupation mémoire (mémoire occupée,
mémoire libre, mémoire swap, ...)
● L’occupation du processeur (taux
d'occupation, ...)
43. Taille mémoire cache
update TABLE_A_MODIFIER
set FIELD1 = FIELD1 + 1, FIELD2=' ' where (FIELD3>0)
Après tuning du cache
44. Les requêtes couteuses
● Attention, il faut bien paramétrer la taille de la
mémoire cache avant.
● MySQL propose un « slow query log »
● Oracle propose une vue
● Sinon plusieurs outils proposent de le faire
45. Autres
● Hibernate
● Activer ou désactiver le mode trace
d'hibernate
● Application
● Les fonctions les plus consommatrices.
46. Sommaire
● Procédure de test
● Définition de la stratégie de test
● Faire un test de charge
● Quand faire un test de charge
● Quoi mesurer/vérifier
● Quand donner les résultats
● Que va t-on trouver
● Procédure
● Rapport d'audit
47. Quand donner les résultats
● Au fur et à mesure car généralement cela induit
des décision importantes dont le cycle de
décision peut être relativement long.
● par exemple lancer des procédures d'achat de
matériel lors d'un dimensionnement
d'infrastructure, commander l'intervention d'une
expertise externe/interne, migration vers une
version plus récente de la librairie.
48. Sommaire
● Procédure de test
● Définition de la stratégie de test
● Faire un test de charge
● Quand faire un test de charge
● Quoi mesurer/vérifier
● Quand donner les résultats
● Que va t-on trouver
● Procédure
● Rapport d'audit
49. Que va t-on trouver
● Des mauvaises pratiques de conception ou de
développement,
● Une architecture logicielle qui ne privilégie pas les
performances,
● Un hardware sous dimensionné,
● Un mauvais paramétrage du serveur d'applications,
● Un mauvais paramétrage du serveur de bases de
données,
● Un mauvais paramétrage des frameworks (hibernate, ...)
● Problème d'utilisation de cache,
● ...
50. Sommaire
● Procédure de test
● Définition de la stratégie de test
● Faire un test de charge
● Quand faire un test de charge
● Quoi mesurer/vérifier
● Quand donner les résultats
● Que va t-on trouver
● Procédure
● Rapport d'audit
51. Procédure
● Capture scénario
● Paramétrage scénario
● Corrélation, variabilisation, think time, ...
● Regroupement dans un plan de test
● Paramétrage du plan de test
● Faire un tir unitaire/de référence
● Permet d'étalonner les scénarios et de collecter des temps de
réponse nominaux
● Exécuter le scénario
● Le tir doit être assez long pour monter en charge et obtenir des
moyennes significatives
● Récupérer les metrics
● Faire un rapport d'audit
54. JMeter Demo
● Bonne documentation
● Open Source et gratuit
● De nombreux protocoles supportés
● …
● http://jakarta.apache.org/jmeter/
55. Sommaire
● Procédure de test
● Définition de la stratégie de test
● Faire un test de charge
● Quand faire un test de charge
● Quoi mesurer/vérifier
● Quand donner les résultats
● Que va t-on trouver
● Procédure
● Rapport d'audit
70. Tuning
● Attention , la taille de la heap ne doit pas
dépasser la taille mémoire physique de la
machine.
● Il peut être utile de mettre la même valeur pour
-Xmx (maximum) et -Xms (minimum) afin
d'éviter les redimensionnement de la heap.
● Attention lorsque il y a beaucoup de JSP
72. Vérification des
paramètres
● Utiliser YourKit Java Profiler ou VisualVM ou ...
73. OutOfMemoryError
● Exception in thread "main":
java.lang.OutOfMemoryError: Java heap space
● Problème de paramétrage de la taille de la
heap
● Fuite mémoire
● Paramètre JVM : -Xmx
● Profiler/Dump
74. OutOfMemoryError
● Exception in thread "main":
java.lang.OutOfMemoryError: PermGen space
● Beaucoup de classes
● Beaucoup d'objets String (String.intern ou
ClassLoader.defineClass dans la stack trace)
● Paramètre JVM : -XX:MaxPermSize
● jmap -permgen
75. OutOfMemoryError
● Exception in thread "main":
java.lang.OutOfMemoryError: Requested array
size exceeds VM limit
● Utilisation de tableaux trop grands par
rapport à la taille de la heap
● Paramètre -Xmx
● Profiler/Dump
76. OutOfMemoryError
● Exception in thread "main":
java.lang.OutOfMemoryError: request <size>
bytes for <reason>. Out of swap space?
● Fuite mémoire
● Serveur trop chargé en mémoire (autres
applications, ...)
● Profiler/Dump
● Monitoring du serveur
77. OutOfMemoryError
● Exception in thread "main":
java.lang.OutOfMemoryError: <reason> <stack
trace> (Native method)
● Problème mémoire détecté lors d'une
interaction avec une application native à
l'aide de JNI
● Profiler/Dump
● Monitoring du serveur
78. Le coût du GC
● Si le temps utilisé par GC est supérieur à 25%
c'est qu'il y a un problème.
● Heap trop petite
● Trop d'objet
● Profiler/Dump
● Paramètre JVM : -Xmx
● Findbugs/PMD
● Modification de la stratégie du GC
● Pas d'appels explicite du GC :
-XX:-DisableExplicitGC
80. Diag Bdd
● Faire intervenir un DBA si nécessaire
81. Utiliser des index
update TABLE1 MxT3 set (T1.FIELD1) = (select T2.FIELD1 from TABLE2 T2
where (T1.FIELD2 = T2.FIELD3 )) where exists (select 1 from TABLE2 T2
where (T1.FIELD2 = T2.FIELD3 ))
Après
create index TABLE2_N98
on TABLE2 (FIELD3,FIELD1)
82. Limiter au maximum les
valeurs récupérées
● Pas de select *
● Conditions dans la clause where
83. Utiliser des Prepared
Statements
● Seulement pour les requêtes appelées de
nombreuses fois
PreparedStatement pstmt = con.prepareStatement("UPDATE
table SET i = ? WHERE j = ?");
pstmt.setLong(1, 123);
pstmt.setLong(2, 100);
Paramétrer le cache Prepared
Statements dans le serveur JavaEE
et/ou dans le driver JDBC
84. Éviter les commits trop
fréquents
setAutoCommit(false);
// Executer toute les requêtes
ExecuteUpdate();
85. Utiliser des Batch Updates
Connection con = DriverManager.getConnection(.......);
Statement stmt = con.createStatement();
stmt.addBatch("INSERT INTO Adresse .......");
stmt.addBatch("INSERT INTO Contacte .......");
int[] countUpdates = stmt.executeBatch();
86. Paramétrer le pool de
connexion JDBC
● Trouver la bonne taille lors des tests (regarder
le nombre de connexions en attente, la charge
CPU, ...).
Pour éviter la création de connexions
au mauvais moment, on peut fixer la
même valeur pour le min et le max
87. Libérer les ressources JDBC
● Libérer les ressources JDBC dans la clause
finally du try catch
● Utiliser Spring Jdbc template
● Utiliser Commons DbUtils
Findbugs
88. Diag thread
● Dead lock
● Au moins 2 threads se bloquent pour accéder à une
ressource.
● Race conditions
● Au moins 2 threads entrent en compétition pour
obtenir une ressource et donc le nombre de threads
augmente et il faut de plus en plus de temps pour
accéder à la ressource.
89. Diag thread
● Thread Leak
● On crée des thread sans fin jusqu'à avoir un
OutOfMemory: unable to create new native thread.
● Problème de configuration du pool de thread
● Le nombre de thread configuré dans le pool est
supérieur au nombre maximum de thread de la
JVM
90. Diag HTTP
● Une gestion des dates d'expiration sur les
ressources statiques couplée à un cache au
niveau des frontaux http pour soulager
l'infrastructure.
● Par exemple une image qui ne change pas
régulièrement peut avoir une date d'expiration
lointaine afin qu'à chaque requête, il n'y ait pas
de vérification sur l'existence d'une nouvelle
version.
91. Session
● Attention au volume des données stockées en
session car cela peut provoquer une
dégradation significative des performances
dans le cas notamment où la réplication de
session est activée.
92. Diag affichage
● Compression des ressources statiques
(images, fichiers flashs, scripts, ...)
● Mettre en place une politique d'expiration des
ressources statiques,
● Activer la compression HTTP
● Utiliser des CSS sprite
● CSS en début de page
● Javascript en fin de page
93. Diag Hibernate
● Optimisation du mapping hibernate pour réduire
significativement le nombre de requêtes
exécutées sur la base de données.
● Mes préconisations sont :
● D'initialiser les relations en mode différé (par
défaut)
● Puis au cas par cas s'assurer que ce mode de
chargement ne génère pas les problèmes dits de
N+1 ou les produits cartésiens.
● Optimiser les modes de chargement en utilisant les
techniques de chargement groupé, chargement par
sous select, etc.
94. Conseils
● Commencer les tests dès que possible
● Automatiser le maximum de tests
● Faire intervenir un DBA
● Faire de l'itératif
● Ne faire varier qu'un paramètre à la fois
● Communiquer
● ...