Identifier le goulot d'étranglement sur un serveur Web

Monitoring system avec atop

Tout serveur a ses limites.

Lorsque son activité atteint sa capacité maximale, l'arrêt de service guette.

Voici une démarche simple pour intervenir en urgence sur un serveur Web Linux en attendant un audit approfondi et des solutions long termes pour éviter les bottleneck.

Les objectifs sont :

  • d'identifier l'origine d'un effondrement des performances
  • de procéder à des interventions d'urgence pour revenir à un niveau de service minimal

Le serveur brûle !

  • pas de panique, pas de décision sans mesure
  • identifier la source du problème : CPU, RAM, Disque, Réseau
  • identifier l'application ou l'évènement qui sature le serveur
  • optimiser ou corriger l'application ou l'évènement

La disponibilité d'un serveur respecte le principe de Pareto en suivant une courbe de puissance, dite Head / Long tail.
La majorité des problèmes graves sera provoquée par des défaillances du calculateur ou des entrées-sorties vers les espaces de travail, de stockage ou de communication.

Les problèmes courants sont :

  • CPU utilisé à 100%
  • RAM utilisée à 100%
  • I/O disque lentes
  • réseau lent

Identifier la source du problème

Contrôler la charge du serveur

La commande uptime affiche la charge du serveur

$ uptime
16:58:40 up 1 day,  6:38,  7 users,  load average: 15.2, 6.8, 0.52

Les 3 valeurs de load average représentent le nombre de processus actifs durant la dernière minute, les 5 dernières minutes et les 15 dernières minutes. Ces valeurs permettent de déterminer la tendance de la charge du serveur ainsi que sa disponibilité.

Une charge de 4 pour un quadri-processeur représente une occupation de 100% de chaque CPU pendant la période de la mesure.
L'occupation ne représente pas la consommation CPU mais son indisponibilité. Par exemple, la CPU peut passer son temps à attendre après les IO disques ou réseaux.

Contrôler l'activité CPU

La commande top est une commande qui affiche la liste des processus les plus actifs avec leur consommation CPU et mémoire.

top - 17:22:36 up 1 day,  7:02,  7 users,  load average: 0.36, 0.50, 0.55
Tasks: 133 total,   2 running, 131 sleeping,   0 stopped,   0 zombie
Cpu(s): 14.6%us,  1.3%sy,  0.0%ni, 84.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   2065572k total,  2012388k used,    53184k free,    39088k buffers
Swap:  1775140k total,    45052k used,  1730088k free,   463268k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            
 6023 www-data   20   0 1028m 828m  32m S   33  41.1 471:04.98 java            
 5272 mysql      20   0  388m  67m  10m S    1   3.3  26:54.68 mysql               
23543 sylvain    20   0  138m  48m  29m S    1   2.4   1:08.91 X11             
 1070 sylvain     20   0 73840  23m  11m R    1  1.2   0:19.44 gnome-terminal     
 5948 sylvain     20   0 21920 7980 6708 S    1  0.4   0:09.60 gpilotd            
 5695 sylvain     20   0 91520  46m  15m S    0  2.3   1:06.10 nautilus           
27722 www-data    20   0  515m 205m  36m S    0 10.2   7:26.13 apache               

Je vous recommande à sa place la commande atop plus évoluée qui :

  • affiche sur le même tableau de bord les informations du type top, free, vmstat, netstat
  • peut masquer les périphériques sans activité
  • affiche les variations de consommation des périphériques
  • colorie les périphériques surchargés

Contrôler les disques

Contrôler l'espace disques disponible

df -h : vérifier que les disques ne sont pas pleins

$ df
Sys. de fich.          Tail. Occ.  Disp. %Occ. Monté sur
/dev/sda3              15G  6,5G   7,5G  47% /
varrun               1009M  136K 1009M   1% /var/run
varlock              1009M  4,0K 1009M   1% /var/lock
udev                 1009M   56K 1009M    1% /dev
lrm                  1009M   39M  970M    4% /lib/modules/2.6.24-21-generic/volatile
/dev/sda5              15G  6,9G   6,7G  51% /data  

Contrôler l'activité des IO disques

Les IO disques sont des opérations lentes qui ralentissent considérablement les processus d'un serveur.
Cette activité est générée par l'utilisation de fichier de log, de fichiers temporaires, la manipulation de gros volume de données... Elles augmente considérablement lorsque le serveur manque de mémoire et swap.

La commande vmstat donne un aperçu de l'activité des disques.

$ vmstat 1 10
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
4  1 324928   8936 172448 129368   12   12    64    23  113  151  6  1 92  1
0  2 324928   8800 172584 129460    0    0 48256    16 1729 3741  7 22 49 21
0  2 324928   9496 172132 129364    0    0 51968    8 1895 4168  7 26 48 19
1  1 324928   9564 172180 129084    0    0 49643    0 1755 3645  8 29 43 20
0  2 324928   8768 172780 129168    0    0 55573    0 1945 3968  7 27 47 18
2  1 324928   9048 172684 129060    0    0 53504    0 1833 3962  9 26 48 17
1  2 324928   8972 173180 128496    0    0 57894    12 1962 3927  7 29 49 16
1  2 324928   8792 173456 128492    0    0 56026    4 1883 4287  5 29 47 19
2  1 324928   9344 172872 128568    0    0 55121    8 1898 3788  8 26 47 19
1  1 324928   9488 171312 130884    0    0 58025    0 1908 3683  5 29 48 18

La valeur principale à surveiller est la colonne wa wait qui indique le temps d'attente des CPU de la fin d'exécution d'opération IO sur les disques.
Les valeurs secondaires sont :

  • l'espace mémoire libre, colonne free. Quand cette valeur s'annule, le serveur est en péril immédiat.
  • l'activité de swap, colonne si et so. Quand ces valeurs ne sont pas nuls, il manque de la mémoire RAM.

Contrôler les users

Qui fait quoi : w

$ w 
14:50:36 up 14 days, 4:20, 4 users, load average: 0,28, 0,21, 0,10 
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT 
root tty1 - 09Jan08 14days 0.14s 0.14s -bash 
guest pts/0 :0.0 10:35 0.00s 0.20s 0.00s dd 
laurent pts/1 :0.0 14:47 2:10m 0.18s 0.18s bash

Qui a fait quoi : last

$ last 
root tty7 :0 Wed Jan 9 11:03 gone - no logout reboot system boot 2.6.22-14-generi Wed Jan 9 10:30 - 14:49 (14+04:18) 
root pts/0 :0.0 Wed Jan 9 10:17 - crash (00:13) 
root pts/2 :0.0 Tue Jan 8 18:49 - 18:50 (00:00) 
root pts/1 :0.0 Tue Jan 8 18:49 - crash (15:41) 
root pts/1 :0.0 Tue Jan 8 17:31 - 17:35 (00:04) 
root pts/0 :0.0 Tue Jan 8 16:59 - 17:38 (00:38) 
root pts/1 :0.0 Tue Jan 8 11:38 - 15:07 (03:28) 
root pts/0 :0.0 Tue Jan 8 11:33 - 15:07 (03:33) 
root pts/2 :0.0 Mon Jan 7 13:34 - 18:12 (04:37) 
root pts/0 :0.0 Mon Jan 7 10:30 - 09:59 (23:29) 
root tty7 :0 Mon Jan 7 09:56 - crash (2+00:34)

Intervention urgente

Le serveur Web sature le CPU :

  • minimiser les jobs actifs
  • simplifier l'application : moins de code = plus de vitesse
  • utiliser un Opcode pour cacher le PHP
  • étudier les logs pour optimiser les paramètres des applications
  • désactiver les modules inutiles
  • cacher les pages
  • planifier les opérations de maintenance et d'optimisation (base, cache, update...)

Le serveur Web sature la mémoire :

  • supprimer les modules inutiles du serveur Web et du serveur d'application
  • réduire le paramètre Apache MaxClients
  • ajouter de la mémoire physique

La base de données sature la CPU :

  • cacher les requêtes
  • optimiser les requêtes les plus gourmandes
  • optimiser l'utilisation des connexions
  • cacher les index en mémoire

La base de données sature la mémoire :

  • augmenter la mémoire
  • purger les données inutiles
  • installer des disques rapides

Les disques tournent en continus :

  • trop de log
  • trop de fichiers temporaires
  • un système RAID inadapté

Le réseau sature :

  • envoyer moins d'information et les compresser
  • mettre en place un réseau rapide
  • limiter la bande passante de certain port
  • limiter le nombre d'utilisateurs parallèle