Introduction à Siege
Siege est un utilitaire de test de charge et de benchmarking pour serveurs HTTP, fonctionnant sous Linux. Il permet de simuler de multiples utilisateurs accédant simultanément à une application web, supportant les requêtes GET et POST. Cet outil est idéal pour évaluer la résistance d'un service Django face à un trafic intensif.
Installation de l'outil
Pour installer Siege à partir des sources sur un système CentOS, exécutez la séquence de commandes suivante :
wget http://download.joedog.org/siege/siege-3.0.8.tar.gz
tar -zxvf siege-3.0.8.tar.gz
cd siege-3.0.8
./configure
make && make install
Validez l'installation en vérifiant la version :
siege -V
Paramètres courants de la ligne de commande
-c [N]: Définit le nombre d'utilisateurs simultanés (ex: 200).-r [N]: Nombre de répétitions du test.-f [file]: Utilise un fichier contenant une liste d'URLs à tester.-b: Mode "benchmark", supprime les délais entre les requêtes.-t [time]: Durée totale du test (ex: 5M pour 5 minutes).
Indicateurs de performence clés
Lorsqu'un test se termine, Siege affiche un rapport détaillé. Voici les points essentiels à surveiller :
- Transaction rate : Nombre moyen de transactions traitées par seconde par le serveur. C'est l'indicateur de débit principal.
- Availability : Pourcentage de requêtes ayant réussi.
- Response time : Temps de réponse moyen pour chaque requête.
- Concurrency : Nombre moyen de connexions ouvertes simultanément.
- Failed transactions : Nombre total d'échecs (erreurs 4xx ou 5xx).
Scénario de test
Le test est effectué sur une instance modeste (1 vCPU, 1 Go de RAM) avec Django 2.0 et Python 3.7. L'application effectue une opération de lecture simple dans une base de données MySQL sans couche de cache.
La commande de test simule 255 utilisateurs pendant 60 secondes :
siege -c255 -t60S -v -b 127.0.0.1:8000
Comparaison des serveurs d'application
1. Le serveur de développement (runserver)
Utiliser le serveur natif de Django pour les tests de charge :
python3 manage.py runserver 0.0.0.0:8000
Les résultats avec runserver sont généralement médiocres (environ 160 transactions/sec dans ce contexte) avec un taux d'échec élevé. Cela confirme que cet outil est strictement réservé au développement local et ne doit jamais être utilisé en production en raison de sa nature monothreadée.
2. Déploiement avec uWSGI
uWSGI est un serveur d'application haute performence. Configuration avec 8 processus de travail :
uwsgi --http :8000 --module application.wsgi --processes 8
Avec uWSGI, on observe une nette amélioration de la stabilité. Le débit augmente et le nombre d'erreurs diminue significativement par rapport au serveur de développement.
3. Déploiement avec Gunicorn
Gunicorn est un serveur WSGI Python utilisnat un modèle de "pre-fork worker". Il permet l'utilisation de threads pour gérer l'IO.
Exemple de lancement avec 4 workers et 50 threads :
gunicorn --env DJANGO_SETTINGS_MODULE=projet.settings projet.wsgi:application -w 4 -b 0.0.0.0:8000 --threads 50 -k gthread
Les performances de Gunicorn sont comparables à celles d'uWSGI. Sur une configuration matérielle limitée (1 Go RAM / 1 CPU), le seuil de saturation se situe généralement autour de 200-250 connexions concurrentes avant que les temps de latence ne deviennent critiques.
Observations techniques
Bien que Django offre une productivité élevée et une prise en main rapide, ses performances brutes en haute concurrence sur du matériel limité peuvent être un goulot d'étranglement. Pour des besoins de microservices nécessitant une latence extrêmement faible ou un débit massif, des alternatives comme Tornado (asynchrone) ou des langages compilés comme Go (avec le framework Iris ou Gin) peuvent être envisagés pour compléter l'écosystème Django.