Python est réputé pour être simple et amusant à utiliser, pour faciliter le développement de logiciels et pour ses performances d'exécution qui dépasseraient celles des autres langages scriptés. (Bien que la dernière version de PHP, PHP 7, puisse donner du fil à retordre à Python.)
Tout le monde souhaite que son site Web et son application fonctionnent plus rapidement. De plus, tout site Web dont le trafic augmente ou connaît des pics de trafic importants est vulnérable aux problèmes de performances et aux temps d’arrêt, qui surviennent souvent aux heures les plus difficiles, c’est-à-dire les plus chargées. De plus, presque tous les sites Web souffrent de problèmes de performances et de temps d’arrêt, que le volume de trafic augmente régulièrement ou qu’ils connaissent de fortes augmentations d’utilisation.
C'est là qu'interviennent NGINX et NGINX Plus. Ils améliorent les performances du site Web de trois manières différentes :
NGINX et NGINX Plus offrent des avantages que vous les utilisiez comme serveur Web pour votre application Python, comme serveur proxy inverse, comme équilibreur de charge ou pour ces trois objectifs.
Dans ce premier article d'une série en deux parties, nous décrivons cinq conseils pour améliorer les performances de vos applications Python, notamment l'utilisation de NGINX et NGINX Plus comme serveur Web, comment implémenter la mise en cache des fichiers statiques et la micromise en cache des fichiers générés par l'application. Dans la partie 2 , nous décrirons comment utiliser NGINX et NGINX Plus comme serveur proxy inverse et comme équilibreur de charge pour plusieurs serveurs d'applications.
Il existe deux conditions très différentes dans lesquelles les performances de votre application Python sont importantes : premièrement, avec un nombre quotidien « raisonnable » d’utilisateurs ; et deuxièmement, sous de lourdes charges. De nombreux propriétaires de sites se soucient trop peu des performances sous des charges légères, alors que – à notre humble avis – ils devraient transpirer toutes les dixièmes de seconde en termes de temps de réponse. Réduire les temps de réponse de quelques millisecondes est un travail difficile et ingrat, mais cela rend les utilisateurs plus heureux et les résultats commerciaux meilleurs.
Cependant, cet article de blog et la partie 2 qui l'accompagne se concentrent plutôt sur le scénario qui inquiète tout le monde : les problèmes de performances qui surviennent lorsqu'un site est occupé, comme des ralentissements importants des performances et des plantages. En outre, de nombreuses attaques de pirates informatiques imitent les effets d’une augmentation soudaine du nombre d’utilisateurs, et l’amélioration des performances du site constitue souvent également une étape importante pour répondre aux attaques .
Avec un système qui alloue une certaine quantité de mémoire par utilisateur, comme Apache HTTP Server, l'ajout d'utilisateurs entraîne une surcharge de la mémoire physique à mesure que de plus en plus d'utilisateurs s'accumulent. Le serveur commence à échanger des données sur le disque, les performances chutent et des performances médiocres et des pannes s'ensuivent. Le passage à NGINX, comme décrit dans cet article de blog, permet de résoudre ce problème.
Python est particulièrement sujet aux problèmes de performances liés à la mémoire, car il utilise généralement plus de mémoire pour accomplir ses tâches que les autres langages de script (et les exécute donc plus rapidement). Ainsi, toutes choses étant égales par ailleurs, votre application basée sur Python peut « tomber en panne » sous une charge utilisateur plus faible qu’une application écrite dans un autre langage.
L'optimisation de votre application peut aider quelque peu, mais ce n'est généralement pas le moyen le plus efficace ni le plus rapide de résoudre les problèmes de performances du site liés au trafic. Les étapes décrites dans cet article de blog et la partie 2 qui l’accompagne constituent les moyens les plus efficaces et les plus rapides pour résoudre les problèmes de performances liés au trafic. Ensuite, après avoir suivi les étapes indiquées ici, n'hésitez pas à revenir en arrière et à améliorer votre application, ou à la réécrire pour utiliser une architecture de microservices .
Les petits sites Web fonctionnent bien lorsqu'ils sont déployés sur un seul serveur. Les grands sites Web nécessitent plusieurs serveurs. Mais si vous vous trouvez dans la zone grise intermédiaire – ou si votre site passe d’un petit site à un grand site – vous avez des choix intéressants à faire.
Si vous disposez d’un déploiement sur un seul serveur, vous courez un risque important en cas de pics de trafic ou de croissance rapide du trafic global. Votre évolutivité est limitée, avec des correctifs possibles qui incluent l'amélioration de votre application, le passage de votre serveur Web à NGINX, l'obtention d'un serveur plus grand et plus rapide ou le déchargement du stockage vers un réseau de diffusion de contenu (CDN). Chacune de ces options prend du temps à mettre en œuvre, a un coût et risque d’introduire des bugs ou des problèmes de mise en œuvre.
De plus, avec un déploiement sur un seul serveur, votre site présente par définition un seul point de défaillance – et de nombreux problèmes pouvant mettre votre site hors ligne n’ont pas de solutions rapides ou simples.
Si vous basculez votre serveur vers NGINX dans un déploiement à serveur unique, vous pouvez choisir librement entre NGINX Open Source et NGINX Plus. NGINX Plus inclut un support de niveau entreprise et des fonctionnalités supplémentaires . Certaines fonctionnalités supplémentaires, telles que la surveillance des activités en direct , sont pertinentes pour un déploiement à serveur unique, et d’autres, telles que l’équilibrage de charge et la persistance des sessions , entrent en jeu si vous utilisez NGINX Plus comme serveur proxy inverse dans un déploiement multiserveur.
Tout bien considéré, à moins que vous ne soyez sûr que votre site restera petit pendant longtemps et que les temps d’arrêt ne constituent pas une préoccupation majeure, le déploiement d’un serveur unique comporte certains risques. Le déploiement multiserveur est presque arbitrairement évolutif – les points de défaillance uniques peuvent être éliminés et les performances peuvent être celles que vous choisissez, avec la possibilité d'ajouter rapidement de la capacité.
Aux débuts du Web, le nom « Apache » était synonyme de « serveur Web ». Mais NGINX a été développé au début des années 2000 et gagne progressivement en popularité ; il est déjà le serveur Web n°1 parmi les 1 000, 10 000, 100 000 et [ngx_snippet name='proportion-top-sites'] mondiaux.
NGINX a été développé pour résoudre le problème C10K , c'est-à-dire pour gérer plus de 10 000 connexions simultanées dans un budget mémoire donné. D'autres serveurs Web ont besoin d'une grande quantité de mémoire pour chaque connexion. Ils manquent donc de mémoire physique et ralentissent ou plantent lorsque des milliers d'utilisateurs souhaitent accéder à un site en même temps. NGINX gère chaque demande séparément et s'adapte gracieusement à un plus grand nombre d'utilisateurs. (Il est également excellent à d’autres fins, comme nous le décrirons ci-dessous.)
Un aperçu de haut niveau de l’architecture de NGINX est présenté ci-dessous.
Dans le diagramme, un serveur d'application Python s'intègre dans le bloc Serveur d'application du backend et est affiché en cours d'accès par FastCGI. NGINX ne « sait » pas comment exécuter Python, il a donc besoin d'une passerelle vers un environnement qui le sait. FastCGI est une interface largement utilisée pour PHP, Python et d'autres langages.
Cependant, un choix plus populaire pour la communication entre Python et NGINX est l'interface Web Server Gateway (WSGI). WSGI fonctionne dans des environnements multithread et multiprocessus, il s'adapte donc bien à toutes les options de déploiement mentionnées dans cet article de blog.
Si vous passez à NGINX comme serveur Web, de nombreuses informations sont disponibles pour vous aider à suivre les étapes à suivre :
Cet extrait montre comment vous pouvez configurer NGINX pour l'utiliser avec uWSGI – dans ce cas, un projet utilisant le framework Python Django :
http { # ...
django en amont {
serveur 127.0.0.1:29000;
}
serveur {
écoute 80;
nom_serveur monapp.exemple.com;
racine /var/www/monapp/html;
emplacement / {
index index.html;
}
emplacement /static/ {
alias /var/django/projects/monapp/static/;
}
emplacement /main {
inclure /etc/nginx/uwsgi_params;
uwsgi_pass django;
uwsgi_param Hôte $host;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
}
}
}
La mise en cache du contenu statique consiste à conserver une copie des fichiers qui ne changent pas très souvent (ce qui peut signifier toutes les quelques heures ou jamais) à un emplacement autre que le serveur d'applications. Un exemple typique de contenu statique est une image JPEG affichée dans le cadre d’une page Web.
La mise en cache de fichiers statiques est un moyen courant d’améliorer les performances des applications, et elle se produit en fait à plusieurs niveaux :
La mise en œuvre de la mise en cache de fichiers statiques sur le serveur Web présente deux avantages :
La mise en cache de fichiers statiques fonctionne bien avec une implémentation à serveur unique, mais le matériel sous-jacent est toujours partagé par le serveur Web et le serveur d’applications. Si le matériel du serveur Web est occupé à récupérer un fichier mis en cache – même de manière très efficace – ces ressources matérielles ne sont pas disponibles pour l’application, ce qui peut la ralentir dans une certaine mesure.
Pour prendre en charge la mise en cache du navigateur, définissez correctement les en-têtes HTTP pour les fichiers statiques. Tenez compte de l’en-tête HTTP Cache-Control
(et de son paramètre max-age
en particulier), de l’en-tête Expires
et des balises Entity
. Pour une bonne introduction au sujet, consultez Utilisation de NGINX et NGINX Plus comme passerelle d’application avec uWSGI et Django dans le Guide d’administration de NGINX Plus.
Le code suivant configure NGINX pour mettre en cache les fichiers statiques, notamment les fichiers JPEG, GIF, PNG, vidéo MP4, Powerpoint et bien d'autres. Remplacez www.example.com par l'URL de votre serveur Web.
server { # remplacez l'URL de votre serveur Web par "www.example.com"
server_name www.example.com;
root /var/www/example.com/htdocs;
index index.php;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
try_files $uri =404;
include fastcgi_params;
# remplacez le socket, ou l'adresse et le port, de votre serveur Python
fastcgi_pass unix:/var/run/php5-fpm.sock;
#fastcgi_pass 127.0.0.1:9000;
}
emplacement ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg
|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid
|midi|wav|bmp|rtf)$ {
expire max;
log_not_found désactivé;
access_log désactivé;
}
}
Le microcaching exploite une énorme opportunité d'améliorer les performances sur les serveurs d'applications exécutant Python, PHP et d'autres langages. À des fins de mise en cache, il existe trois types de pages Web :
La micromise en cache est utile pour le deuxième type de page décrit ci-dessus : les pages générées par l’application et non personnalisées. « Micro » fait référence à une brève période de temps. Lorsque votre site génère la même page plusieurs fois par seconde, cela ne nuira peut-être pas beaucoup à la fraîcheur de la page si vous la mettez en cache pendant une seconde. Cependant, cette brève période de mise en cache peut considérablement décharger le serveur d’applications, en particulier lors des pics de trafic. Au lieu de générer 10, 20 ou 100 pages (avec le même contenu) pendant la période d'expiration du cache, il génère une page donnée une seule fois, puis la page est mise en cache et diffusée à de nombreux utilisateurs à partir du cache.
L’effet est en quelque sorte miraculeux. Un serveur qui est lent lorsqu'il traite des dizaines de requêtes par seconde devient assez rapide lorsqu'il en traite une seule. (Plus, bien sûr, toutes les pages personnalisées.) Notre propre Owen Garrett a un article de blog qui détaille les avantages de la micromise en cache , avec du code de configuration. Le changement principal, la configuration d’un cache proxy avec un délai d’expiration d’une seconde, ne nécessite que quelques lignes de code de configuration.
proxy_cache_path /tmp/cache keys_zone=cache:10m levels=1:2 inactive=600s max_size=100m;server {
proxy_cache cache;
proxy_cache_valid 200 1s;
# ...
}
Pour plus d'exemples de configuration, consultez le blog de Tyler Hicks-Wright sur Python et uWSGI avec NGINX .
Dans la première partie, nous avons passé en revue les solutions permettant d'augmenter les performances d'une implémentation Python sur un seul serveur, ainsi que la mise en cache, qui peut être déployée sur une implémentation sur un seul serveur ou peut être exécutée sur un serveur proxy inverse ou un serveur de mise en cache distinct. (La mise en cache fonctionne mieux sur un serveur séparé.) La partie suivante, Partie 2 , décrit les solutions de performances qui nécessitent deux serveurs ou plus.
Si vous souhaitez explorer les fonctionnalités avancées de NGINX Plus pour votre application, telles que le support, la surveillance des activités en direct et la reconfiguration à la volée, démarrez votre essai gratuit de 30 jours dès aujourd'hui ou contactez-nous pour discuter de vos cas d'utilisation .
« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."