Mise en mémoire tampon du proxy NGINX : optimisation des performances et de l'espace disque

Mise en mémoire tampon NGINX détermine à quelle vitesse et avec quelle efficacité en termes de mémoire votre proxy reçoit les réponses de l'upstream, les met en mémoire tampon et les envoie aux clients. Je vais vous montrer comment réduire la latence, libérer rapidement les connexions au backend et optimiser le Mémoire en gardant le contrôle sur cela.

Points centraux

Les aspects clés suivants m'aident à trouver le juste équilibre entre performances et consommation de mémoire.

  • Découplage La communication entre le client et le backend réduit le temps de connexion et augmente le débit.
  • Tailles des tampons Sélectionnez « exact » pour économiser de la mémoire vive et éviter les E/S disque.
  • tampons occupés limiter la mémoire active pendant la transmission.
  • Exceptions relatives au streaming fonctionner correctement sans mise en mémoire tampon.
  • Suivi et des tests de charge garantissent la fiabilité de chaque modification.

Comment fonctionne la mise en mémoire tampon par proxy dans NGINX

J'utilise activement Mise en mémoire tampon, afin que NGINX récupère rapidement les réponses de l'upstream et les transmette ensuite de manière autonome aux clients. Cette dissociation réduit la Latence côté serveur, car l'application est prête plus rapidement et ferme sa connexion plus tôt. Alors que les clients se chargent à des vitesses variables, la couche proxy synchronise l'envoi depuis la mémoire vive. Si les données ne tiennent pas entièrement dans la mémoire vive, NGINX peut temporairement recourir à des fichiers et ainsi transmettre la réponse de manière fiable. C’est précisément ce comportement qui stabilise les systèmes fortement sollicités avec de nombreuses connexions simultanées Connexions.

Quand la mise en mémoire tampon active est-elle la meilleure option ?

Pour les applications web classiques, les API avec des tailles de réponse moyennes ou les piles WordPress, cela offre Mise en mémoire tampon obtient régulièrement les meilleurs résultats. Je libère plus tôt le backend, tandis que NGINX prend en charge le reste du transfert vers des réseaux clients souvent hétérogènes. Cela permet d'augmenter l'efficacité Débit, surtout lorsque de nombreuses requêtes sont traitées simultanément. Ceux qui regroupent plusieurs services derrière un proxy inverse bénéficient en outre d'une répartition contrôlée de la charge. Pour les questions d'architecture relatives aux proxys, une présentation claire m'aide à Architecture de proxy inverse, qui sépare clairement les rôles et les limites.

Stockage ou E/S : le budget adéquat

Je gère l'équilibre entre la mémoire vive et les accès au disque dur, car des tampons trop petits entraînent des E/S disque provoquer des problèmes et des tampons trop volumineux alourdissent la mémoire par connexion. Les facteurs déterminants sont la taille typique des réponses, les requêtes parallèles et la Vitesse du client. Dans l'idéal, les petites réponses restent entièrement en mémoire vive (RAM), ce qui permet à NGINX de les transmettre sans délai aux destinataires plus lents. Les corps de message très volumineux peuvent être stockés sur disque, mais dans ce cas, je veille à utiliser des disques rapides et à mettre en place des limites pour éviter un nombre excessif d'opérations d'E/S. Cet équilibre permet de maintenir la Temps de réponse faible et protège le système contre la pression d'accumulation.

Aperçu des directives et des valeurs indicatives

Je définis de manière ciblée les paramètres clés afin de contrôler la mémoire et le comportement d'envoi. Le premier tampon pour les en-têtes de réponse est associé à proxy_buffer_size; cela permet d'éviter les erreurs liées à des en-têtes trop volumineux et d'économiser des transferts en mémoire vive inutiles. Je répartis les données de réponse proprement dites via proxy_buffers sous forme de paires « nombre × taille », afin que les « bodies » restent entièrement en mémoire vive, dans la mesure du possible. Avec proxy_busy_buffers_size Je limite le nombre de tampons déjà enregistrés pour l'envoi afin de réduire la consommation de mémoire active. Je base les tailles types sur les pages de mémoire (4 à 32 Ko) et sur les profils de réponse connus de mes applications.

directive Effet Valeurs typiques Remarques
proxy_buffering Marche/Arrêt de la mise en mémoire tampon activé (par défaut) Laisser activé pour les applications web standard ; vérifier pour la diffusion en direct
proxy_buffer_size tampon d'en-tête 8k–16k Une taille trop petite entraîne l'erreur „ upstream sent too big header “
proxy_buffers Tampon de protection pour le corps 8 × 16k, 16 × 16k Lier aux tailles de réponse et au parallélisme
proxy_busy_buffers_size Limite du tampon d'envoi 32k–128k Un débit suffisant, sans monopoliser la mémoire vive
proxy_max_temp_file_size Limite de disque 0 à 1 g 0 désactive les fichiers temporaires
proxy_temp_path Chemin d'accès pour les fichiers temporaires Chemin d'accès au SSD Enregistrer sur un support de données rapide

Profils concrets et exemples de calculs

J'estime grossièrement les besoins en mémoire par connexion active comme étant la somme de proxy_buffer_size plus (N × taille du tampon) issu de proxy_buffers. Avec 8 tampons de 16 ko plus 16 ko d'en-tête, on arrive à environ 144 ko par requête, tant que tout reste en mémoire vive. Avec 5 000 requêtes simultanées, j'estime donc l'occupation pure de la mémoire tampon à environ 720 Mo, auxquels s'ajoute la surcharge liée à la Processus. Lorsque le trafic augmente, les besoins augmentent également ; c’est pourquoi je définis les marges de manière à ce que les réponses typiques puissent s’y adapter, sans pour autant considérer les cas exceptionnels avec des corps de message surdimensionnés comme la norme. Si nécessaire, je limite les exceptions à l’aide de Limites de disque, afin de faire face aux pics de demande de mémoire.

Quand je désactive volontairement la mise en mémoire tampon

Les API en temps réel, les événements envoyés par le serveur ou la vidéo en direct nécessitent une connexion directe Débit sans mise en mémoire tampon supplémentaire. Dans ce genre de cas, je désactive proxy_buffering et je mise sur une approche efficace Streaming. Le proxy transmet alors immédiatement les données, ce qui évite les pics de latence pour les données en temps réel, mais maintient la connexion au backend ouverte plus longtemps. Pour ces cas de figure, il est intéressant de se pencher sur Streaming de réponse, y compris un réglage judicieux des keepalive et des délais d'expiration. Il reste important de garder à l'esprit la consommation de ressources plus élevée par connexion et de fixer des limites en conséquence.

Définir de manière ciblée les tampons occupés

Avec proxy_busy_buffers_size Je contrôle ainsi la quantité de mémoire „ prête à être envoyée “ qui reste bloquée simultanément. Si la limite est trop basse, la distribution est ralentie ; si elle est trop élevée, les pics de RAM augmentent. Je choisis donc une valeur correspondant à 1 à 2 fois la taille du tampon, afin que NGINX achemine rapidement les paquets sans trop Mémoire à lier. Pour les clients lents, j'accepte un peu plus d'espace « busy » afin de réduire le risque de changements de contexte fréquents. Les réseaux rapides tirent profit de valeurs plus faibles, qui permettent de Besoin de mémoire permettre une bonne prévisibilité.

Fichiers temporaires : chemin d'accès, taille, limites

J'active les Fichiers uniquement lorsque les objets volumineux sont traités de manière réaliste ou que la mémoire vive est insuffisante. Si les fichiers temporaires sont stockés sur un SSD, les temps de réponse restent acceptables ; sur un disque lent, les opérations d'E/S ralentissent rapidement l'ensemble du système Fil de discussion. Grâce à proxy_max_temp_file_size, je me prémunis contre une occupation excessive ; en cas de doute, je fixe une limite stricte. En cas de nombreuses réponses volumineuses en parallèle, je prévois suffisamment d’espace et je surveille l’utilisation réelle. Lorsque de la mémoire RAM est disponible, je privilégie des tampons plus volumineux et je conserve les éléments critiques dans le Mémoire.

Réglage itératif, indicateurs de performance et tests

Je commence par des traitements conservateurs Valeurs, mesurez, ajustez et recommencez le cycle. Les indicateurs clés sont la latence, le taux d'erreur, les pics de RAM, les temps d'attente d'E/S et l'utilisation de la Travailleur. Les tests de charge permettent de mettre en évidence des effets qui passent inaperçus au quotidien, comme les pics d'en-têtes dus aux cookies ou les méga-réponses occasionnelles. En complément, j'ajuste les paramètres de connexion et des workers de manière coordonnée, par exemple Worker‑Connections et Keepalive. Je vérifie chaque modification de manière rigoureuse afin d'évaluer l'impact de la Tampon peut clairement l'attribuer.

Mise en mémoire tampon des requêtes et téléchargements

Les tampons de réponse ne représentent qu'une partie de la vérité. Du côté de l'entrée, c'est proxy_request_buffering, si NGINX met d'abord entièrement en mémoire tampon les corps des requêtes client (par exemple, les fichiers téléchargés) ou s'il les transmet immédiatement en amont. Pour les API qui reçoivent des fichiers volumineux, je désactive souvent la mise en mémoire tampon des requêtes : le serveur en amont reçoit le flux plus tôt, les délais d’expiration diminuent et NGINX n’a pas besoin de stocker temporairement les corps volumineux sur le disque. L’inconvénient : la connexion en amont reste ouverte plus longtemps et dépend davantage de la vitesse du client. Pour les formulaires classiques ou les requêtes JSON plus petites, la mise en mémoire tampon des requêtes reste activée afin de lisser correctement les pics de trafic et de mieux contrôler les ressources du serveur. Je combine cela avec client_max_body_size et une client_body_buffer_size, afin que les valeurs aberrantes soient rejetées dès leur apparition ou correctement amorties.

Gérer Pro-Response : X-Accel-Buffering, Chunked et longueurs

Pour un réglage plus précis, je désactive la mise en mémoire tampon par réponse via Mise en mémoire tampon X-Accel Extrait de la partie en amont : l'en-tête „ X-Accel-Buffering: no “ indique à NGINX de diffuser la réponse directement, même si l'option proxy_buffering est activée globalement. J'utilise cette option pour le SSE, le long polling ou les flux de diagnostic, sans pour autant compromettre les réglages généraux. De plus, je veille à ce que Longueur du contenu, dans la mesure du possible : si NGINX connaît la longueur, il planifie les zones de mémoire tampon et les fichiers temporaires de manière plus prévisible que s’il se basait exclusivement sur chunked est transféré. Lorsque la longueur est inconnue (par exemple, pour les flux en direct), j'estime les besoins de manière prudente et je configure les E/S avec des limites. Pour les pages d'erreur ou les petites réponses JSON, je laisse la mise en mémoire tampon strictement activée afin que le circuit en amont soit libéré rapidement.

Compression et protocoles : coup d'œil sur HTTP/2/3

La compression et la mise en mémoire tampon doivent être envisagées conjointement. Est-ce que gzip ou Brotli activé, la compression tire parti des blocs de données contigus en mémoire vive (RAM). Des tampons trop petits peuvent limiter le débit, car le compresseur doit changer de contexte plus fréquemment. Je choisis donc des tailles de tampon qui regroupent bien les segments de réponse typiques, sans pour autant saturer la mémoire vive par connexion. Sous HTTP/2 et HTTP/3 Grâce au multiplexage et au contrôle de flux, la vitesse d'envoi varie selon chaque flux ; la mise en mémoire tampon stabilise le côté backend, tandis que NGINX synchronise les flux de manière fluide. Important : sur les liaisons très sensibles à la latence, réduire légèrement l'espace occupé (Busy-Space) peut aider à atténuer les effets „ Head-of-Line “ ; sur les liaisons « puissantes » dotées de grandes fenêtres, j'alloue un peu plus d'espace occupé afin de maintenir une performance d'envoi maximale.

Cache proxy et requêtes par plage : interaction avec les tampons

Qui proxy_cache , il convient de coordonner le budget alloué aux tampons et aux fichiers temporels. NGINX peut à la fois mettre en cache les réponses et les transmettre aux clients ; une mémoire vive (RAM) suffisante pour les tampons réduit la durée de la connexion au backend, tandis que le « cache hit » découple complètement les requêtes ultérieures. Je limite plus strictement les fichiers temporaires lorsque le cache est « chaud » et je les ouvre tant que le taux de réussite est en cours de constitution. Dans le cas de Demandes concernant la gamme (Téléchargements partiels) : je décide soit de les servir directement à partir du cache, soit de les laisser d'abord se charger entièrement dans la mémoire tampon. Les séries fréquentes de fichiers volumineux bénéficient de tailles de mémoire tampon finement équilibrées et, en option, de réponses segmentées, afin que ni les E/S disque ni la RAM ne deviennent incontrôlables.

Clients lents : maîtriser le débit sans épuiser la mémoire vive

La plupart des effets de mise en mémoire tampon ne se manifestent qu'avec des clients très lents. Je configure send_timeout et en option limit_rate/limit_rate_after, afin de protéger les destinataires hésitants sans mobiliser indûment les workers. En cas de forte limitation du débit, les tampons « Busy » doivent augmenter, sous peine de blocages ; parallèlement, je contrôle le nombre de connexions parallèles par adresse IP afin de désamorcer les schémas pathologiques. Pour les téléchargements avec une clientèle hétérogène (mobile, Wi-Fi, fibre optique), des valeurs de « Busy » modérées et des tampons de corps (body buffer) un peu plus généreux sont utiles, afin que NGINX continue à envoyer les données de manière linéaire alors que l’amont est déjà occupé par la requête suivante.

Exécution dans des conteneurs et orchestration

Je prévois cela dans des conteneurs proxy_temp_path À noter : soit un volume hôte rapide (SSD), soit un tmpfs si la mémoire vive est suffisante. Les limites des conteneurs (mémoire/CPU/stockage éphémère) ont un impact direct sur les tampons et les fichiers temporaires ; je prévois une marge suffisante pour les pics de charge et j'ajuste en conséquence le nombre de workers parallèles et de connexions. Il est important de garder à l'esprit ulimit -n (descripteurs de fichiers) et les quotas de l'Orchestrator : si la mémoire éphémère est trop petite, les fichiers temporaires génèrent des erreurs ; si la RAM est insuffisante, les workers tombent sous la pression OOM. Je dimensionne les tampons de manière à ce que les pics de charge typiques restent stables dans les limites des conteneurs, et je surveille en permanence l’espace réellement occupé par les répertoires temporaires.

Paramètres par défaut et modèle pour les applications Web courantes

Je pars d'un profil succinct, que j'affine ensuite à l'aide de données de mesure. Exemple :

location / {
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_buffering on;

    # Mémorisation des en-têtes et du corps des requêtes
    proxy_buffer_size 16k;
    proxy_buffers 16 16k;
    proxy_busy_buffers_size 64k;

    # Fichiers temporaires uniquement en dernier recours
    proxy_max_temp_file_size 256m;
    proxy_temp_path /var/cache/nginx/proxy_temp 1 2;

    # Délais d'attente et envoi
    proxy_read_timeout 60s;
    send_timeout 30s;

 # Facultatif : streaming de téléchargement selon l'API
    # proxy_request_buffering off;
}

Ainsi, les réponses de taille moyenne restent entièrement en mémoire vive (RAM), l’upstream est libéré rapidement et les fichiers temporaires ne sont utilisés qu’en cas de valeurs aberrantes. Au deuxième tour, j'adapte le nombre de tampons au parallélisme réel, j'augmente légèrement la taille du « Busy » si nécessaire en cas de réponses courtes et fréquentes, et je limite davantage les fichiers temporaires dès que le taux de réussite du cache est satisfaisant.

Surveillance et journalisation : rendre les effets visibles

Je mesure systématiquement : $request_time et $upstream_response_time dans le journal d'accès, indiquent si l'amont est déconnecté prématurément. 1 TP 4 To envoyés et $body_bytes_sent permettent de faire correspondre les profils de tampon avec le trafic réel. Si l'écart entre le temps en amont et la durée totale diminue, les tampons fonctionnent correctement. Je mets cela en corrélation avec les pics de RAM, l'attente d'E/S et l'utilisation de la proxy_temp_path. Lors des tests de résistance, je fais varier les vitesses des clients, les tailles des réponses et la charge des en-têtes (par exemple, les cookies) afin de détecter les cas limites. Ce n’est que lorsque les métriques des logs et les valeurs système se situent de manière stable dans ma fourchette cible que je finalise le profil et que je documente les limites ainsi que les procédures d’escalade (tampons plus importants, autre politique de température, répliques supplémentaires).

Problèmes courants et solutions

Le message „l'en-tête envoyé en amont est trop volumineux“ Je résous ce problème en augmentant la valeur de `proxy_buffer_size` et, si nécessaire, celle des `proxy_buffers`. Si des délais d'attente surviennent sur des terminaux lents, j'augmente modérément les délais d'attente d'envoi et je libère un peu d'espace dans les tampons occupés. Si le répertoire temporaire se remplit, je réduis la taille maximale ou j’augmente les tampons RAM, en fonction du rapport coût-bénéfice. Si la diffusion est saccadée, je vérifie les goulots d’étranglement d’E/S, la saturation du processeur et la répartition des Tampon. Lorsque je suis confronté à des situations de pénurie, je commence toujours par m'appuyer sur des données mesurées, et non sur des doublesments généralisés.

Conclusion : mes points de contrôle pour la mise en cache du proxy NGINX

Je commence par définir les Tailles de réponse, les pics de charge et les profils des clients, avant même de régler les tampons. Ensuite, je définis un tampon d'en-tête suffisamment grand pour éviter les erreurs inutiles. Je dimensionne les tampons de corps de manière à ce que les réponses habituelles restent en mémoire vive et que seules les exceptions soient stockées sur disque Je configure les « Busy Buffers » de manière à ce que les transferts s'effectuent de manière fluide, sans gaspiller de mémoire. Pour finir, je vérifie le tout à l'aide de tests de charge et d'outils de surveillance, jusqu'à ce que la latence, le débit et les besoins en mémoire atteignent un niveau fiable. Fenêtre sont couchés.

Derniers articles