Debug des performances serveur
Ce guide vous aide à identifier et résoudre les problèmes de performances sur votre VPS.
Diagnostic rapide
Vue d'ensemble avec htop
# Installer htop
sudo apt install htop
# Lancer
htop
Raccourcis htop :
F6: Trier par CPU, RAM, etc.F9: Tuer un processusF5: Vue arborescenteq: Quitter
Indicateurs clés
# Charge système
uptime
# Résultat : load average: 0.50, 0.75, 0.60
# = charge sur 1min, 5min, 15min
Interprétation du load average (pour un VPS avec N coeurs) :
- < N : Normal
- = N : Utilisation maximale
-
N : Surcharge
# Voir le nombre de coeurs
nproc
Analyser l'utilisation CPU
Identifier les processus gourmands
# Top 10 par CPU
ps aux --sort=-%cpu | head -11
# En temps réel
top -o %CPU
CPU par processus dans le temps
# Surveiller un processus spécifique
pidstat -p PID 1
Profiler un service
# Installer perf
sudo apt install linux-tools-common linux-tools-$(uname -r)
# Profiler pendant 30 secondes
sudo perf top -p PID
Analyser l'utilisation mémoire
Vue d'ensemble
free -h
total used free shared buff/cache available
Mem: 3.8Gi 2.1Gi 200Mi 100Mi 1.5Gi 1.4Gi
Swap: 2.0Gi 500Mi 1.5Gi
available: Mémoire réellement utilisablebuff/cache: Cache système (libérable si nécessaire)
Détail par processus
# Top 10 par RAM
ps aux --sort=-%mem | head -11
# Avec plus de détails
ps aux --sort=-%mem | awk 'NR<=11{printf "%-10s %-8s %-8s %s\n", $1, $4"%", $6/1024"MB", $11}'
Fuites mémoire
# Surveiller la mémoire d'un processus dans le temps
watch -n 1 "ps -p PID -o pid,rss,vsz,pmem,comm"
Si la RAM augmente continuellement = fuite mémoire.
Swap utilisé
# Voir le swap par processus
for file in /proc/*/status ; do
awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file 2>/dev/null
done | sort -k 2 -n -r | head -10
Analyser les I/O disque
Vue d'ensemble
# Installer iotop
sudo apt install iotop
# Lancer
sudo iotop -o
Statistiques I/O
# Installer sysstat
sudo apt install sysstat
# Stats I/O toutes les secondes
iostat -x 1
Colonnes importantes :
%util: Utilisation du disque (>80% = goulot d'étranglement)await: Temps d'attente I/O (>20ms = lent)r/s,w/s: Lectures/écritures par seconde
Identifier les processus I/O
# Processus avec le plus d'I/O
sudo iotop -o -b -n 3
Analyser le réseau
Bande passante
# Installer iftop
sudo apt install iftop
# Surveiller
sudo iftop -i eth0
Connexions actives
# Nombre de connexions par état
ss -s
# Connexions établies
ss -tn state established
# Connexions par IP
ss -tn | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -10
Débit réseau
# Installer nload
sudo apt install nload
# Surveiller
nload eth0
Problèmes courants et solutions
CPU à 100%
Cause : Processus emballé
# Identifier
top -o %CPU
# Solution : Redémarrer le service
systemctl restart nom_du_service
# Ou tuer le processus (dernier recours)
kill -9 PID
Cause : Attaque ou spam
# Vérifier les connexions
ss -tn | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head
# Bloquer une IP
sudo ufw deny from IP_SUSPECTE
RAM saturée
Solution immédiate :
# Vider le cache (sans risque)
sync; echo 3 | sudo tee /proc/sys/vm/drop_caches
Solution long terme :
- Augmenter le swap
- Optimiser l'application
- Upgrade le VPS
Disque I/O lent
Cause : Logs trop volumineux
# Identifier
du -h /var/log/ | sort -hr | head
# Nettoyer
sudo journalctl --vacuum-size=500M
Cause : Requêtes base de données
# Voir les requêtes lentes MySQL
sudo mysqladmin -u root -p processlist
Latence réseau
# Tester
ping -c 10 google.com
mtr google.com
Optimisations courantes
MySQL/MariaDB
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# Cache de requêtes
query_cache_type = 1
query_cache_size = 64M
# Buffers
innodb_buffer_pool_size = 512M
innodb_log_file_size = 128M
# Connexions
max_connections = 100
Nginx
sudo nano /etc/nginx/nginx.conf
worker_processes auto;
worker_connections 1024;
# Gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript;
# Cache
open_file_cache max=1000 inactive=20s;
PHP-FPM
sudo nano /etc/php/8.1/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
Paramètres système
sudo nano /etc/sysctl.d/99-performance.conf
# Réseau
net.core.somaxconn = 65535
net.ipv4.tcp_max_tw_buckets = 1440000
net.ipv4.tcp_fin_timeout = 15
# Fichiers
fs.file-max = 65535
sudo sysctl -p /etc/sysctl.d/99-performance.conf
Script de diagnostic complet
#!/bin/bash
# /usr/local/bin/diagnose.sh
echo "=== DIAGNOSTIC PERFORMANCES $(date) ==="
echo ""
echo "--- Système ---"
echo "OS: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
echo "Kernel: $(uname -r)"
echo "Uptime: $(uptime -p)"
echo "Load: $(uptime | awk -F'load average:' '{print $2}')"
echo ""
echo "--- CPU ---"
echo "Coeurs: $(nproc)"
echo "Top 5 CPU:"
ps aux --sort=-%cpu | head -6 | tail -5 | awk '{printf " %-20s %s%%\n", $11, $3}'
echo ""
echo "--- Mémoire ---"
free -h | grep -E "Mem|Swap"
echo "Top 5 RAM:"
ps aux --sort=-%mem | head -6 | tail -5 | awk '{printf " %-20s %s%%\n", $11, $4}'
echo ""
echo "--- Disque ---"
df -h | grep -E "^/dev"
echo ""
echo "--- Réseau ---"
echo "Connexions: $(ss -s | grep estab | awk '{print $4}' | cut -d, -f1)"
echo ""
echo "--- Services critiques ---"
for svc in nginx apache2 mysql mariadb php-fpm; do
if systemctl is-active --quiet $svc 2>/dev/null; then
echo " $svc: OK"
fi
done
echo ""
echo "=== FIN DIAGNOSTIC ==="
sudo chmod +x /usr/local/bin/diagnose.sh
Monitoring continu
Avec Netdata (recommandé)
# Installation
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
# Accès : http://VOTRE_IP:19999
Alertes avec cron
#!/bin/bash
# /usr/local/bin/perf-alert.sh
# Seuils
CPU_THRESHOLD=80
MEM_THRESHOLD=85
DISK_THRESHOLD=90
# Vérification CPU (load average)
LOAD=$(uptime | awk -F'load average:' '{print $2}' | cut -d, -f1 | xargs)
CORES=$(nproc)
LOAD_PCT=$(echo "$LOAD $CORES" | awk '{printf "%.0f", ($1/$2)*100}')
# Vérification RAM
MEM_PCT=$(free | grep Mem | awk '{printf "%.0f", $3/$2 * 100}')
# Vérification Disque
DISK_PCT=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
# Alertes
if [ $LOAD_PCT -gt $CPU_THRESHOLD ]; then
echo "ALERTE CPU: ${LOAD_PCT}%"
fi
if [ $MEM_PCT -gt $MEM_THRESHOLD ]; then
echo "ALERTE RAM: ${MEM_PCT}%"
fi
if [ $DISK_PCT -gt $DISK_THRESHOLD ]; then
echo "ALERTE DISQUE: ${DISK_PCT}%"
fi
Conseil
Pour un monitoring professionnel, consultez le guide Monitoring serveur.