Surcharge serveur

Quand votre serveur ne tient plus la charge

CPU à 100%, RAM saturée, files d’attente qui explosent : identifiez et résolvez.

Les symptômes typiques

Vous êtes probablement face à une surcharge serveur si :

  • Le site était lent avant de tomber (pas une coupure brutale)
  • Les erreurs 503 sont intermittentes (ça marche, puis non, puis oui…)
  • Vous avez eu un pic de trafic récent (campagne, article viral, promo)
  • Le serveur répond très lentement même en SSH
  • Les fichiers statiques (images, CSS) chargent mais pas les pages PHP

Une surcharge n’est pas une panne : votre serveur fonctionne, il est juste submergé. La bonne nouvelle : c’est généralement réversible rapidement.

Diagnostic en 5 commandes

Connectez-vous en SSH et exécutez ces commandes :

1. Load average (charge globale)

$ uptime
 14:32:01 up 45 days, load average: 12.50, 8.30, 4.20
                                    │      │     │
                                    │      │     └─ Moyenne 15 min
                                    │      └─ Moyenne 5 min
                                    └─ Moyenne 1 min

# Règle : load average > nombre de CPU = surcharge
$ nproc
4
# Ici : 12.50 > 4 = serveur surchargé (3x la capacité)
Load / CPUÉtatAction
< 1✅ TranquilleRien à faire
1 – 2⚠️ ChargéSurveiller
2 – 4?? SurchargeInvestiguer
> 4?? CritiqueAction immédiate

2. Utilisation CPU et RAM

$ top -bn1 | head -20

top - 14:32:01 up 45 days,  4 users,  load average: 12.50, 8.30, 4.20
Tasks: 203 total,  15 running, 188 sleeping,   0 stopped,   0 zombie
%Cpu(s): 94.2 us,  3.1 sy,  0.0 ni,  2.1 id,  0.3 wa,  0.0 hi,  0.3 si
MiB Mem :  16384.0 total,    512.3 free,  14821.2 used,   1050.5 buff/cache
MiB Swap:   4096.0 total,   1024.0 free,   3072.0 used.    892.1 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
15234 www-data  20   0  512340 245612   8432 R  89.3  1.5   12:34.56 php-fpm
15235 www-data  20   0  498220 231004   8124 R  78.2  1.4   11:22.33 php-fpm
15236 www-data  20   0  501832 238456   8256 R  72.1  1.5   10:45.12 php-fpm

Ce qu’il faut regarder :

  • %Cpu(s): 94.2 us → 94% CPU utilisé (??)
  • MiB Mem: 512.3 free → Seulement 512 Mo libres (??)
  • php-fpm en tête → Ce sont les workers PHP qui consomment

3. Qui consomme quoi ?

# Top 10 processus par CPU
$ ps aux --sort=-%cpu | head -10

# Top 10 processus par RAM
$ ps aux --sort=-%mem | head -10

# Nombre de processus PHP actifs
$ ps aux | grep php-fpm | wc -l
48

# Nombre de connexions HTTP actives
$ ss -tuln | grep -E ':(80|443)' | wc -l
1247

4. État de PHP-FPM

$ systemctl status php8.2-fpm

● php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager
     Active: active (running)
   Main PID: 1234
     Status: "Processes active: 50, idle: 0, Requests: 15234"
                                    │
                                    └─ 0 idle = tous les workers occupés !

# Logs PHP-FPM
$ tail -20 /var/log/php8.2-fpm.log
[WARNING] server reached pm.max_children setting (50), consider raising it
# ⚠️ Ce message = vous avez atteint la limite

5. Espace disque et I/O

# Espace disque
$ df -h
Filesystem      Size  Used Avail Use%
/dev/sda1       100G   98G    2G  98%   # ?? Critique !

# Activité disque
$ iostat -x 1 3
Device         r/s     w/s   await  %util
sda          450.00  120.00  45.23  98.50  # ?? Disque saturé

Les 5 causes principales

Pic de trafic légitime

Situation : Campagne marketing, article viral, passage TV, Black Friday.

Diagnostic :

# Requêtes par seconde dans les logs
$ tail -10000 /var/log/nginx/access.log | awk '{print $4}' | cut -d: -f1-3 | uniq -c
    250 26/Dec/2024:14:30
    890 26/Dec/2024:14:31  # ← Pic brutal
    920 26/Dec/2024:14:32

Solutions immédiates :

  • Activer un cache agressif (page caching)
  • Augmenter temporairement les ressources (scale up)
  • Mettre en file d’attente les visiteurs (Cloudflare Waiting Room)

Bot agressif / Crawler

Situation : Un bot scanne votre site de façon intensive (SEO, scraping, indexation).

Diagnostic :

# Top 10 IPs par nombre de requêtes
$ awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
  15234 185.191.171.44  # ← SemrushBot
   8921 66.249.66.91    # ← Googlebot
   7845 114.119.128.45  # ← Bot chinois suspect

Solutions immédiates :

# Bloquer une IP
$ iptables -A INPUT -s 114.119.128.45 -j DROP

# Ou dans Nginx
# deny 114.119.128.45;

# Limiter les bots via robots.txt
# User-agent: SemrushBot
# Crawl-delay: 10

Workers PHP insuffisants

Situation : Configuration PHP-FPM sous-dimensionnée pour le trafic.

Diagnostic :

$ grep -E "pm\.(max_children|start_servers|min_spare|max_spare)" /etc/php/8.2/fpm/pool.d/www.conf
pm.max_children = 5        # ← Beaucoup trop bas !
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Solution : Augmenter pm.max_children selon votre RAM disponible.

; Règle : max_children = RAM disponible (Mo) / Mémoire par processus PHP (Mo)
; Exemple : 8 Go RAM, 128 Mo par process = 8000 / 128 = ~60

pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
$ systemctl restart php8.2-fpm

Requêtes lentes / Boucles

Situation : Un script PHP tourne en boucle ou des requêtes SQL non optimisées bloquent.

Diagnostic :

# Requêtes PHP en cours depuis longtemps
$ ps aux | grep php | awk '$10 > "00:30" {print}'

# Slow queries MySQL
$ tail -50 /var/log/mysql/slow-query.log

# Processus MySQL actifs
$ mysql -e "SHOW PROCESSLIST;" | grep -v Sleep

Solutions :

  • Identifier et optimiser la requête lente
  • Ajouter des index MySQL manquants
  • Killer les processus bloqués : kill -9

Mémoire insuffisante (OOM)

Situation : Le serveur manque de RAM et le kernel tue des processus.

Diagnostic :

# Vérifier les OOM kills récents
$ dmesg | grep -i "out of memory"
$ grep -i "killed process" /var/log/syslog

# Utilisation swap
$ free -h
              total        used        free
Mem:           8Gi       7.8Gi       200Mi
Swap:          4Gi       3.9Gi       100Mi  # ← Swap presque plein = RAM saturée

Solutions :

  • Augmenter la RAM (upgrade serveur)
  • Réduire pm.max_children PHP
  • Optimiser la consommation mémoire des applications
  • Ajouter du swap temporairement

Solutions immédiates (urgence)

Quand le serveur est surchargé et que le site est down, voici les actions rapides :

Action 1 : Identifier et killer les processus gourmands

# Identifier
$ top -bn1 | head -15

# Killer un processus spécifique
$ kill -9 <PID>

# Killer tous les processus PHP (attention !)
$ pkill -9 php-fpm
$ systemctl restart php8.2-fpm

Action 2 : Bloquer le trafic suspect

# Bloquer une IP agressive
$ iptables -A INPUT -s <IP_SUSPECTE> -j DROP

# Bloquer un range
$ iptables -A INPUT -s 114.119.0.0/16 -j DROP

# Sauvegarder les règles
$ iptables-save > /etc/iptables.rules

Action 3 : Activer un mode dégradé

/etc/nginx/conf.d/emergency.conf

# Cache statique d'urgence
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=emergency:10m max_size=1g;

server {
    # ... config existante ...
    
    location / {
        # Servir depuis le cache si backend down
        proxy_cache emergency;
        proxy_cache_valid 200 5m;
        proxy_cache_use_stale error timeout http_503;
        
        # Limiter les connexions par IP
        limit_conn addr 10;
        limit_req zone=one burst=20 nodelay;
    }
}

Action 4 : Activer la maintenance le temps de résoudre

# Activer la maintenance avec estimation
$ echo "3600" > /var/www/monsite/.maintenance

# Vérifier
$ curl -I https://monsite.com
HTTP/1.1 503 Service Unavailable
Retry-After: 3600

La maintenance vous donne le temps de diagnostiquer calmement sans que les visiteurs continuent d’affluer et d’aggraver la surcharge.

Optimisations long terme

Une fois l’urgence passée, mettez en place ces optimisations pour éviter que ça se reproduise :

Niveau 1 : Cache applicatif

WordPress

# Installer un plugin de cache
wp plugin install wp-super-cache --activate

# Ou Redis Object Cache
wp plugin install redis-cache --activate
wp redis enable

PrestaShop

# Activer le cache Smarty
# Back-office > Paramètres avancés > Performances
# Cache : Activer
# Type de cache : Système de fichiers

# Activer CCC (Combine, Compress, Cache)

Niveau 2 : Configuration PHP-FPM optimisée

/etc/php/8.2/fpm/pool.d/www.conf

; Configuration pour serveur 8 Go RAM

[www]
user = www-data
group = www-data

listen = /run/php/php8.2-fpm.sock

; Process Manager
pm = dynamic
pm.max_children = 50          ; RAM / ~150Mo par process
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500         ; Recycle les workers (évite memory leaks)

; Timeouts
request_terminate_timeout = 60s
request_slowlog_timeout = 10s
slowlog = /var/log/php-fpm/slow.log

; Status page (pour monitoring)
pm.status_path = /fpm-status

Niveau 3 : Configuration Nginx optimisée

/etc/nginx/nginx.conf

worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    # Buffers
    client_body_buffer_size 10K;
    client_header_buffer_size 1k;
    client_max_body_size 8m;
    large_client_header_buffers 2 1k;

    # Timeouts
    client_body_timeout 12;
    client_header_timeout 12;
    keepalive_timeout 15;
    send_timeout 10;

    # Gzip
    gzip on;
    gzip_comp_level 5;
    gzip_min_length 256;
    gzip_types text/plain text/css application/json application/javascript;

    # Rate limiting
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
    limit_conn_zone $binary_remote_addr zone=addr:10m;
}

Niveau 4 : Mise en place d’un CDN

Un CDN (Cloudflare, Fastly, CloudFront) absorbe le trafic et protège votre serveur :

  • Cache des fichiers statiques en edge
  • Protection DDoS incluse
  • Réduction de charge serveur de 50-80%
  • Waiting Room pour les pics de trafic

Cloudflare propose un plan gratuit suffisant pour la plupart des sites. Pour une configuration avancée ou un CDN premium, Foxop peut vous accompagner.

Monitoring pour anticiper

Ne découvrez plus les surcharges par vos clients. Mettez en place une surveillance proactive :

Métriques à surveiller

MétriqueSeuil warningSeuil critiqueOutil
Load average> 2x CPU> 4x CPUNetdata, Prometheus
CPU %> 80%> 95%top, Grafana
RAM %> 85%> 95%free, Grafana
Workers PHP idle< 50PHP-FPM status
Temps réponse> 2s> 5sUptime monitoring
Requêtes/secondeVariable+200% normalAccess logs

Script de surveillance simple

/usr/local/bin/check-load.sh

#!/bin/bash
# Alerte si load average trop élevé

THRESHOLD=4
LOAD=$(uptime | awk -F'load average:' '{print $2}' | cut -d, -f1 | tr -d ' ')
LOAD_INT=${LOAD%.*}

if [ "$LOAD_INT" -gt "$THRESHOLD" ]; then
    echo "⚠️ ALERTE: Load average à $LOAD (seuil: $THRESHOLD)" | \
    mail -s "[URGENT] Surcharge serveur monsite.com" [email protected]
fi
# Ajouter au cron (toutes les 5 min)
$ crontab -e
*/5 * * * * /usr/local/bin/check-load.sh

Surveillance proactive 24/7

Alertes instantanées, diagnostic automatique, estimation de capacité.

Questions fréquentes

Comment calculer le bon nombre de workers PHP ?

Formule simple : max_children = RAM disponible (Mo) / Mémoire moyenne par process PHP. Pour connaître la mémoire par process : ps --no-headers -o rss -C php-fpm | awk '{sum+=$1} END {print sum/NR/1024 " Mo"}'. Avec 8 Go de RAM et 150 Mo par process, vous pouvez avoir environ 50 workers.

Le load average est élevé mais le CPU est bas, pourquoi ?

Le load average compte tous les processus en attente, pas seulement CPU. Un load élevé avec CPU bas indique souvent des I/O wait (disque lent, NFS, base de données externe). Vérifiez avec iostat -x 1 ou regardez %wa dans top.

Dois-je augmenter la RAM ou le CPU ?

Analysez d’abord le goulot d’étranglement. Si la RAM est constamment > 90% avec du swap utilisé → ajoutez de la RAM. Si le CPU est > 90% mais la RAM OK → ajoutez du CPU ou optimisez le code. Souvent, ajouter de la RAM permet plus de workers PHP, ce qui résout les deux problèmes.

Comment gérer un pic de trafic prévu (Black Friday, lancement) ?

Préparez-vous : activez un CDN avec cache agressif, augmentez temporairement les ressources serveur (scale up), mettez en place une Waiting Room (Cloudflare), désactivez les fonctionnalités non essentielles, et surveillez en temps réel avec des alertes configurées.