Les tests de performance ne s'achèvent pas à la fin de l'exécution. La véritable valeur réside dans l'analyse des résultats, l'identification des goulots d'étranglement et l'optimisation du système pour atteindre vos objectifs de performance. De nombreux facteurs déterminent les performances d'un système. Cette rubrique ne les décrit pas tous, mais fournit un guide pour analyser les performances système.
Les sections suivantes détaillent l'analyse et l'optimisation des performances pour les systèmes exécutés sur Alibaba Cloud. Ce document s'adresse aux développeurs, administrateurs de test, opérateurs de test, ingénieurs de support technique, responsables qualité de projet, chefs de projet et ingénieurs O&M en charge des performances du système.
Analyse des performances
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Surveillance configurée : surveillance côté client dans Performance Testing (PTS), surveillance de l'infrastructure via Cloud Monitor et traçage au niveau de l'application via Application Real-Time Monitoring Service (ARMS).
Contexte technique : connaissances pratiques des systèmes d'exploitation, intergiciels, bases de données et développement d'applications.
Flux d'analyse
Parcourez les couches suivantes de haut en bas. La plupart des problèmes de performance proviennent de la couche réseau ou serveur ; commencez donc par là avant d'examiner le côté client.
Étape 1 : Vérifiez la couche d'accès réseau
Dans les architectures cloud, le trafic des tests de charge n'atteint pas toujours entièrement le backend. Les politiques de protection sur Server Load Balancer (SLB), Web Application Firewall (WAF), adresses IP Anti-DDoS, points de présence (POP) Content Delivery Network (CDN) ou POP Edge Security Acceleration (ESA) peuvent intercepter le trafic lorsque :
La bande passante, le nombre maximal de connexions ou les limites de nouvelles connexions sont dépassées.
Les modèles de trafic ressemblent à des attaques Challenge Collapsar (CC) ou DDoS.
Si vous constatez des erreurs inattendues ou des délais d'expiration malgré une faible charge backend, vérifiez ces services en priorité. Pour plus de détails, consultez Pourquoi des erreurs ou des délais d'expiration se produisent-ils même sous une faible charge backend ?
Étape 2 : Validez les métriques
Vérifiez si le temps de réponse, le débit et le taux d'erreur correspondent à vos objectifs. Si une métrique sort de la plage acceptable, le problème provient presque toujours du côté serveur plutôt que du côté client.
Étape 3 : Inspectez les métriques matérielles
Sur le serveur, vérifiez l'utilisation du CPU, l'utilisation de la mémoire, les E/S disque et les E/S réseau. En cas d'anomalie, approfondissez l'investigation sur la ressource concernée (voir Méthodes d'analyse ci-dessous).
Étape 4 : Inspectez les métriques des intergiciels
Si les métriques matérielles sont normales, examinez les indicateurs au niveau des intergiciels : utilisation des pools de threads, utilisation des pools de connexions, ainsi que la fréquence et la durée du garbage collection (GC).
Étape 5 : Inspectez les métriques de la base de données
Si les métriques des intergiciels sont normales, analysez les performances de la base de données : requêtes SQL lentes, taux de succès du cache, contentions de verrous et paramètres de la base de données.
Étape 6 : Inspectez la logique applicative
Si toutes les métriques d'infrastructure sont normales, le goulot d'étranglement se situe probablement dans le code de l'application. Examinez les algorithmes, les stratégies de mise en tampon et de mise en cache, ainsi que les modèles d'E/S synchrones et asynchrones.
Catégories courantes de goulots d'étranglement
Matériel et spécifications
Le CPU, la mémoire et les E/S disque constituent les goulots d'étranglement matériels les plus fréquents. Des instances sous-dimensionnées ou des limites de spécification peuvent plafonner le débit avant qu'un problème logiciel ne devienne visible.
Intergiciels
Les systèmes de base de données et les serveurs d'applications (y compris les serveurs web) deviennent souvent des goulots d'étranglement en raison d'une mauvaise configuration. Par exemple, des paramètres incorrects du pool de connexions Java Database Connectivity (JDBC) sur une plateforme Weblogic peuvent limiter le traitement simultané des requêtes.
Code applicatif
Les goulots d'étranglement courants au niveau de l'application incluent :
Paramètres Java Virtual Machine (JVM) ou paramètres de conteneur non optimaux
Requêtes SQL lentes (identifiables via les services APM tels qu'ARMS)
Schémas de base de données ou architecture applicative mal conçus
Traitement séquentiel alors qu'un traitement parallèle est possible
Absence de couches de tampon ou de cache
Nombre insuffisant de threads de traitement des requêtes
Modèles producteur-consommateur non coordonnés
Système d'exploitation
Sur les systèmes Windows, UNIX ou Linux, des configurations incorrectes au niveau du système d'exploitation peuvent dégrader les performances. Par exemple, lorsque la mémoire physique est insuffisante et que les paramètres de mémoire virtuelle ne sont pas correctement configurés, une activité de swap excessive augmente considérablement les temps de réponse.
Périphériques réseau
Les pare-feu, équilibreurs de charge, commutateurs et services réseau cloud (SLB, WAF, adresses IP Anti-DDoS, POP CDN et POP ESA) peuvent introduire des goulots d'étranglement. Par exemple, si un équilibreur de charge ne parvient pas à répartir le trafic entre les serveurs lorsqu'un serveur atteint sa capacité maximale, la configuration de l'équilibreur de charge constitue le goulot d'étranglement.
Méthodes d'analyse
CPU
L'utilisation du CPU se décompose en trois catégories, chacune pointant vers une cause racine différente :
CPU User élevé
Un processus au niveau de l'application consomme trop de CPU.
Exécutez
toppour identifier le processus avec la plus forte utilisation du CPU.Exécutez
top -H -p <pid>pour cibler le thread spécifique.Pour les applications Java, utilisez
jstackpour capturer la trace de pile des threads et identifier la méthode gourmande en CPU.Pour les applications C++, utilisez
gprofpour profiler l'exécution.Passez en revue le code source à l'emplacement identifié.
CPU Sys élevé
Le noyau consomme trop de CPU, généralement en raison d'appels système coûteux.
Utilisez
stracepour tracer les appels système et identifier ceux qui consomment le plus de temps.
CPU Wait élevé
Le CPU est inactif en attendant la fin des E/S. Cela est généralement causé par une activité importante de lecture/écriture sur le disque.
Réduisez le volume des journaux.
Basculez vers des E/S asynchrones.
Mettez à niveau vers des disques offrant de meilleures performances IOPS.
Mémoire
Les systèmes d'exploitation utilisent la mémoire libre pour la mise en cache disque, de sorte qu'une utilisation de la mémoire proche de 99 % est normale. Surveillez plutôt :
Un seul processus consommant une quantité disproportionnée de mémoire.
Une activité de swap élevée, indiquant que le système manque de mémoire physique.
E/S disque
La métrique la plus importante pour les E/S disque est le pourcentage d'activité. Pour le réduire :
Diminuez le volume d'écriture des journaux.
Utilisez des E/S asynchrones.
Mettez à niveau vers des disques avec des IOPS plus élevés.
E/S réseau
Le débit réseau dépend de la taille de la charge utile. Maintenez l'utilisation en dessous de 70 % de la capacité maximale du matériel. Pour améliorer les E/S réseau :
Compressez les charges utiles de réponse.
Activez la mise en cache sur les nœuds de calcul.
Regroupez les petites transmissions en moins de transferts plus volumineux.
Paramètres du noyau
Les valeurs par défaut des paramètres du noyau conviennent à la plupart des charges de travail, mais les tests de stress peuvent dépasser ces valeurs par défaut. Utilisez sysctl pour afficher et modifier les paramètres du noyau selon les besoins.
JVM
Surveillez la fréquence et la durée du GC et du full GC :
Exécutez
jstatpour vérifier les statistiques GC.Si les GC sont trop fréquents, utilisez
jmappour vider la mémoire heap.Analysez le dump avec HeapAnalyzer pour identifier la consommation mémoire élevée et les fuites de mémoire potentielles.
Vous pouvez également utiliser un outil APM tel qu'ARMS pour obtenir une vue visuelle et en temps réel des métriques JVM.
Pools de threads
Si les pools de threads sont saturés, augmentez la taille du pool. Si un pool plus grand n'aide pas, approfondissez l'investigation :
Threads bloqués en attente de verrous.
Méthodes avec des temps d'exécution longs.
Requêtes de base de données avec des temps d'attente longs.
Pools de connexions JDBC
Si les pools de connexions sont épuisés, augmentez la taille du pool. Cependant, si la base de données sous-jacente est lente, ajouter des connexions n'aidera pas. Vérifiez :
Les requêtes lentes qui maintiennent les connexions plus longtemps que nécessaire.
Les chemins de code qui ne libèrent pas les connexions vers le pool.
SQL
Un SQL inefficace est l'une des causes les plus fréquentes de mauvaises performances. Examinez le plan d'exécution pour comprendre pourquoi une requête est lente. Le tableau suivant répertorie les problèmes de performance SQL courants.
Problèmes d'index
|
Problème |
Exemple |
Impact |
|
Aucun index |
S/O |
Analyse complète de la table |
|
Fonction sur colonne indexée |
|
Analyse complète de la table |
|
Expression sur colonne indexée |
|
Analyse complète de la table |
|
Conversion de type sur colonne indexée |
|
Analyse complète de la table |
|
Opérateur d'inégalité |
|
Analyse complète de la table |
|
Joker en tête |
|
Analyse complète de la table |
|
Concaténation dans la clause WHERE |
|
Analyse complète de la table |
|
IN avec petite liste de valeurs |
|
Analyse complète de la table |
|
Requête paramétrée |
|
Analyse complète de la table même avec des paramètres |
|
Index non clusterisé avec ORDER BY |
S/O |
Mauvaises performances d'index |
|
Index chaîne vs entier |
|
Les index de type chaîne sont plus lents que les index de type entier |
|
Colonnes nullable |
Colonnes avec des valeurs NULL |
Mauvaises performances d'index |
|
IS NULL / IS NOT NULL |
S/O |
Mauvaises performances d'index |
Problèmes de volume de données
|
Problème |
Exemple |
Impact |
|
SELECT * |
|
Récupère inutilement toutes les colonnes |
|
Grande table sans filtrage |
|
Volume de données important |
|
Requête imbriquée sans filtrage précoce |
Filtrage après chargement complet des données |
Traite des données inutiles |
|
Jointure multi-table sans prédicats sélectifs |
Jointure puis filtrage |
Opérations de jointure excessives |
|
Insertion en bloc |
Insertion de toutes les données en une fois |
Génère des journaux excessifs, utilisation élevée des ressources |
Problèmes de verrouillage et de concurrence
|
Problème |
Exemple |
Impact |
|
Escalade de verrou au niveau ligne |
|
Peut verrouiller toute la table |
|
Interblocages |
A : |
Blocage mutuel |
|
Curseurs |
|
Faibles performances |
|
Tables temporaires (CREATE) |
|
Génère des journaux excessifs |
|
Tables temporaires (DROP) |
|
Doit confirmer la suppression pour éviter un verrouillage prolongé |
Conseils d'optimisation des requêtes
|
Au lieu de |
Utilisez |
Pourquoi |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SQL codé en dur |
SQL paramétré (lié) |
Compilation unique, réutilisation du plan d'exécution |
Optimisation
L'optimisation des performances est un processus itératif. À mesure que les applications évoluent et que la charge utilisateur augmente, des tests et des optimisations réguliers permettent de maintenir le système dans des limites de performance acceptables.
Flux d'optimisation
1. Identifiez le problème
Ciblez la zone problématique :
Code applicatif : les problèmes au niveau du code sont la source la plus fréquente des problèmes de performance. Commencez par vérifier ici.
Paramètres de la base de données : des bases de données mal configurées peuvent ralentir l'ensemble du système. Pour les grandes bases de données, faites examiner les paramètres par un administrateur de base de données (DBA) avant la mise en production.
Paramètres du système d'exploitation : des paramètres OS mal configurés peuvent introduire des goulots d'étranglement au niveau du système.
Matériel : les E/S disque et la mémoire sont les contraintes matérielles les plus courantes.
Réseau : les réseaux surchargés provoquent des pertes de paquets et des pics de latence.
2. Analysez le problème
Une fois la zone problématique identifiée, déterminez son étendue :
Le problème affecte-t-il le temps de réponse, le débit ou les deux ?
Tous les utilisateurs sont-ils affectés, ou seulement un sous-ensemble ? Qu'est-ce qui distingue les utilisateurs affectés ?
Les métriques des ressources système (CPU, mémoire, E/S) sont-elles à ou près de leurs limites ?
Le problème est-il concentré dans des modules ou des endpoints spécifiques ?
Le problème se situe-t-il côté client ou côté serveur ?
La charge réelle dépasse-t-elle la capacité conçue du système ?
3. Définissez les objectifs et les solutions
Améliorez le débit du système et réduisez le temps de réponse pour mieux prendre en charge vos charges de travail. Traduisez ces objectifs en scénarios de test de stress PTS avec des niveaux de charge spécifiques, puis sélectionnez le mode approprié : basé sur la concurrence, basé sur les transactions par seconde (TPS), ou une combinaison d'incrémentation automatique et de régulation manuelle pour la limitation du trafic.
4. Testez la solution
Exécutez des tests de référence après chaque modification. Les tests de référence fournissent des mesures quantitatives et comparables de métriques de performance spécifiques, vous offrant un moyen objectif d'évaluer si la modification a été bénéfique.
5. Évaluez les résultats
Après chaque itération d'optimisation, évaluez :
La modification a-t-elle atteint ou dépassé l'objectif de performance ?
A-t-elle amélioré les performances globales du système, ou seulement un composant spécifique ?
Des itérations d'optimisation supplémentaires sont-elles nécessaires ?
Si les objectifs sont atteints, le cycle d'optimisation est terminé.
Bonnes pratiques
Concevez pour la performance dès le départ. L'optimisation compense les lacunes de conception mais ne peut pas remplacer une bonne architecture. Intégrez les exigences de performance dans la conception et le développement dès le début.
Définissez des objectifs de performance clairs. Traduisez les objectifs en scénarios de test PTS avec des niveaux de charge spécifiques, puis sélectionnez le mode approprié : basé sur la concurrence, basé sur les TPS, ou une combinaison d'incrémentation automatique et de régulation manuelle pour la limitation du trafic.
Validez après chaque modification. Exécutez des tests de régression après chaque itération d'optimisation pour confirmer que la modification fonctionne comme prévu et n'introduit pas de régressions.
Intégrez les tests de performance dans votre flux de travail. Exécutez régulièrement des tests de performance intranet pendant le développement. Effectuez périodiquement des tests de performance métier dans l'environnement de production.
Maintenez l'optimisation itérative. Réinjectez les résultats de chaque cycle dans le développement ultérieur. Le travail sur les performances n'est jamais ponctuel.
Protégez la qualité du code. Ne sacrifiez pas la lisibilité ou la maintenabilité pour la performance. Les optimisations qui rendent le code plus difficile à maintenir créent des coûts à long terme qui surpassent les gains à court terme.
Autre analyse des tests
Taux de réussite
Le taux de réussite est déterminé par les valeurs de retour du serveur et les assertions que vous configurez. Sans assertions, une requête est marquée comme échouée lorsque le backend renvoie un code d'erreur, que le serveur lève une exception ou que la requête expire.
Journaux
Les journaux PTS enregistrent les détails de chaque requête échantillonnée. Avec un taux d'échantillonnage de 10 %, PTS enregistre 10 requêtes sur 100. À 100 %, chaque requête est enregistrée.
Compromis : des taux d'échantillonnage plus élevés vous offrent plus de détails de diagnostic, mais augmentent la charge sur les générateurs de charge, réduisant leurs performances et augmentant les coûts. Le taux d'échantillonnage n'affecte pas le serveur testé.
Établissement de connexion
L'établissement de connexion est le processus de configuration d'une connexion HTTP entre le générateur de charge et le serveur. Le délai d'expiration de la requête couvre toute la période allant de la résolution DNS à la fin de la réponse. Si cette durée dépasse le seuil de délai d'expiration configuré, la requête est marquée comme expirée.