BLOG | NGINX

Optimisation des performances de Python avec NGINX, partie 1 : Service Web et mise en cache

NGINX-Partie-de-F5-horiz-black-type-RGB
Vignette de Floyd Smith
Floyd Smith
Publié le 31 mars 2016

Introduction – Comment NGINX est utilisé avec Python

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 :

  1. En tant que serveur Web , NGINX a été développé à l’origine pour résoudre le problème C10K , c’est-à-dire pour prendre en charge facilement 10 000 connexions simultanées ou plus. L'utilisation de NGINX comme serveur Web pour votre application Python rend votre site Web plus rapide, même à de faibles niveaux de trafic. Lorsque vous avez plusieurs milliers d'utilisateurs, il est pratiquement certain que vous bénéficierez de performances bien supérieures, de moins de pannes et de moins de temps d'arrêt. Vous pouvez également effectuer la mise en cache de fichiers statiques ou la micro-mise en cache sur votre serveur Web NGINX, bien que les deux fonctionnent mieux lorsqu'ils sont exécutés sur un serveur proxy inverse NGINX distinct (voir le paragraphe suivant).
  2. En tant que serveur proxy inverse – Vous pouvez « déposer NGINX » en tant que serveur proxy inverse devant votre configuration de serveur d’applications actuelle. NGINX fait face au Web et transmet les requêtes à votre serveur d’applications. Cette « astuce étrange » permet à votre site Web de fonctionner plus rapidement, de réduire les temps d’arrêt, de consommer moins de ressources serveur et d’améliorer la sécurité. Vous pouvez également mettre en cache des fichiers statiques sur le serveur proxy inverse (très efficace), ajouter la microcaching du contenu dynamique pour réduire la charge sur l'application elle-même, et bien plus encore.
  3. En tant qu’équilibreur de charge pour plusieurs serveurs d’applications , commencez par déployer un serveur proxy inverse. Ensuite, évoluez en exécutant plusieurs serveurs d’applications en parallèle et en utilisant NGINX ou NGINX Plus pour équilibrer la charge du trafic entre eux. Avec ce type de déploiement, vous pouvez facilement adapter les performances de votre site Web aux besoins de trafic, augmentant ainsi la fiabilité et la disponibilité. Si vous avez besoin qu'une session utilisateur donnée reste sur le même serveur, configurez l'équilibreur de charge pour prendre en charge la persistance de session .

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.

Astuce 1 – Trouver les goulots d’étranglement des performances de Python

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 .

Astuce 2 – Choisissez un déploiement sur un seul ou plusieurs serveurs

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.

NGINX et Python fonctionnent ensemble pour offrir des performances grâce aux capacités de NGINX en matière de service Web, d'équilibrage de charge et de mise en cache
« Déposer NGINX devant » les serveurs d'application

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é.

Astuce 3 – Changez votre serveur Web pour NGINX

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.

Guide de configuration de l'architecture pour Python à l'aide des capacités NGINX en matière de service Web, d'équilibrage de charge et de mise en cache
Architecture NGINX, extrait de L'architecture des applications open source, volume II

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;
}
}
}

Astuce 4 – Implémenter la mise en cache des fichiers statiques

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 :

  • Dans le navigateur de l’utilisateur
  • Chez les fournisseurs d’accès Internet à plusieurs niveaux – du réseau interne d’une entreprise au fournisseur d’accès Internet (FAI)
  • Sur un serveur Web, comme nous le décrirons ici

La mise en œuvre de la mise en cache de fichiers statiques sur le serveur Web présente deux avantages :

  • Livraison plus rapide à l’utilisateur – NGINX est optimisé pour la mise en cache de fichiers statiques et exécute les requêtes de contenu statique beaucoup plus rapidement qu’un serveur d’applications.
  • Charge réduite sur le serveur d'applications – Le serveur d'applications ne voit même pas les demandes de fichiers statiques mis en cache, car le serveur Web les satisfait.

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é;
}
}

Astuce 5 – Mettre en œuvre la microcaching

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 :

  • Fichiers statiques – Ceux-ci peuvent être mis en cache, comme décrit dans l’Astuce 4 .
  • Pages générées par l'application et non personnalisées : il n'est généralement pas judicieux de les mettre en cache, car elles doivent être récentes. Un exemple est une page livrée à un utilisateur de commerce électronique qui n'est pas connecté (voir le point suivant) : les produits disponibles, les produits similaires recommandés, etc. peuvent changer constamment, il est donc important de fournir une nouvelle page. Cependant, si un autre utilisateur arrive, disons un dixième de seconde plus tard, il peut être tout à fait acceptable de lui montrer la même page que l'utilisateur précédent.
  • Pages personnalisées générées par l'application : elles ne peuvent pas être mises en cache de manière utile, car elles sont spécifiques à l'utilisateur et il est peu probable que le même utilisateur voie deux fois la même page personnalisée. Un exemple est une page de commerce électronique pour un utilisateur connecté ; la même page ne peut pas être affichée pour d’autres utilisateurs.
Micro-caching avec NGINX
Les fichiers statiques et les fichiers non personnalisés générés par l'application peuvent être mis en cache

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 .

Conclusion

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."