Aller au contenu
Infrastructure · 4 min de lecture

Une seconde de microcache absorbe une pointe de trafic

L'affirmation Mettre une page dynamique en cache pendant une seconde semble futile. C'est pourtant le changement de configuration au meilleur rendement pour un petit site, puisqu'i...

A Rédigé par Administrator
Une seconde de microcache absorbe une pointe de trafic

L'affirmation

Mettre une page dynamique en cache pendant une seconde semble futile. C'est pourtant le changement de configuration au meilleur rendement pour un petit site, puisqu'il convertit un nombre illimité de requêtes par seconde vers l'origine en exactement une. Une page d'accueil qui s'effondre à 90 utilisateurs simultanés en servira 5 000 avec le même matériel et cinq lignes de configuration Nginx.

L'arithmétique

Supposons que votre page d'accueil consomme 180 ms de temps applicatif et que vous disposez de 8 processus de travail. Votre plafond théorique est d'environ :

8 travailleurs / 0,180 s = 44 requetes par seconde

Une mention dans un média local ou un envoi d'infolettre peut produire 400 requêtes par seconde pendant dix minutes. À 44 par seconde, la file croît sans limite et tout le monde obtient une expiration, y compris les clients déjà en train de payer.

Avec un cache d'une seconde, l'origine sert au plus une requête par seconde et par adresse mise en cache, quel que soit le débit d'arrivée. Les 399 autres sortent de la mémoire en moins d'une milliseconde. La charge de votre application pendant la pointe est plus faible qu'un mardi tranquille.

La configuration

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=micro:10m
                 max_size=1g inactive=10m use_temp_path=off;

server {
    location / {
        proxy_pass http://app;
        proxy_cache micro;
        proxy_cache_valid 200 301 1s;
        proxy_cache_lock on;
        proxy_cache_use_stale updating error timeout http_500 http_502 http_503;
        proxy_cache_background_update on;
        add_header X-Cache $upstream_cache_status;
    }
}

Trois de ces lignes font le travail important.

proxy_cache_lock on fait qu'à l'expiration d'une entrée, une seule requête part vers l'origine et les autres l'attendent. Sans cela, les 400 requêtes atteignent votre application à l'instant précis de l'expiration — une ruée par seconde, ce qui est pire que pas de cache du tout.

proxy_cache_use_stale avec les conditions d'erreur énumérées transforme votre cache en filet de sécurité. Si l'application se met à renvoyer des 502, les visiteurs continuent de recevoir la dernière bonne copie au lieu d'une page d'erreur. Cette directive a couvert plus d'erreurs de déploiement que n'importe quelle campagne de tests.

proxy_cache_background_update rafraîchit l'entrée périmée sans faire attendre personne. Combinée à la précédente, aucun visiteur ne paie jamais le coût complet du rendu.

Ne pas mettre en cache les sessions authentifiées

Le risque évident est de servir la session d'un client à un autre. Contournez sur le témoin de session :

proxy_cache_bypass $cookie_session_id;
proxy_no_cache     $cookie_session_id;

Les deux directives sont nécessaires et font des choses différentes : bypass évite la lecture du cache, no_cache évite l'écriture. N'appliquer que la première entraîne le stockage d'une réponse authentifiée, remise plus tard à un visiteur anonyme — la défaillance qui finit en rapport d'incident de confidentialité.

Assurez-vous aussi que votre application pose Cache-Control: private sur toute réponse authentifiée, de sorte qu'une mauvaise configuration en amont ne puisse pas provoquer le même problème.

Vary et la chaîne de requête

Deux autres réglages déterminent si votre taux de succès est de 98 % ou de 3 %. Le premier est la clé de cache. Par défaut, Nginx la construit sur l'URI complète, chaîne de requête comprise : un lien de campagne portant des paramètres de suivi produit donc une entrée distincte pour chaque visiteur. Retirez les paramètres inutilisés avant qu'ils n'atteignent la clé, ou normalisez celle-ci explicitement.

Le second est l'en-tête Vary. Une réponse qui varie selon User-Agent est pratiquement impossible à mettre en cache, tant les valeurs en circulation sont nombreuses. Varier selon Accept-Encoding est normal et attendu. Vérifiez ce que votre cadriciel émet avant de supposer quoi que ce soit.

Vérifiez que cela fonctionne vraiment

curl -sI https://exemple.ca/ | grep -i x-cache
for i in $(seq 1 5); do curl -sI https://exemple.ca/ | grep -i x-cache; sleep 0.3; done

Vous devriez voir MISS puis HIT, HIT, HIT. Si chaque requête est un MISS, un élément de la réponse empêche la mise en cache — généralement un en-tête Set-Cookie sur chaque requête, que Nginx respecte en refusant de stocker la réponse. Beaucoup de cadriciels émettent par défaut un témoin de session aux visiteurs anonymes ; le désactiver pour le trafic anonyme est souvent le seul changement applicatif requis.

Choisir la durée

Une seconde est la valeur par défaut appropriée pour une page d'accueil ou une page de liste très fréquentée : assez courte pour que personne ne perçoive de contenu périmé, assez longue pour aplatir toute pointe réaliste. Dix secondes conviennent à un catalogue. Soixante secondes conviennent à un article. Les seules pages à ne jamais traiter ainsi sont le panier, le paiement et le compte.

La configuration prend quinze minutes. C'est la hausse de capacité la moins chère à votre disposition et, contrairement à l'achat d'une instance plus grosse, elle ne coûte rien par mois.

#nginx #caching #scaling #performance

À lire aussi