Le proxy inversé nginx augmente considérablement la latence du pire cas

(modifier: partiellement compris et travaillé, voir commentaire)

J'ai une configuration avec nginx agissant comme un proxy inverse devant un server d'application CherryPy. J'utilise ab pour comparer les performances en passant par nginx vs not, et en remarquant que le premier cas a bien pire les performances les plus défavorables:

$ ab -n 200 -c 10 'http://localhost/noop' This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking localhost (be patient) Completed 100 requests Completed 200 requests Finished 200 requests Server Software: nginx Server Hostname: localhost Server Port: 80 Document Path: /noop Document Length: 0 bytes Concurrency Level: 10 Time taken for tests: 3.145 seconds Complete requests: 200 Failed requests: 0 Write errors: 0 Total transferred: 29600 bytes HTML transferred: 0 bytes Requests per second: 63.60 [#/sec] (mean) Time per request: 157.243 [ms] (mean) Time per request: 15.724 [ms] (mean, across all concurrent requests) Transfer rate: 9.19 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 1 Processing: 5 48 211.7 31 3007 Waiting: 5 48 211.7 31 3007 Total: 5 48 211.7 31 3007 Percentage of the requests served within a certain time (ms) 50% 31 66% 36 75% 39 80% 41 90% 46 95% 51 98% 77 99% 252 100% 3007 (longest request) $ ab -n 200 -c 10 'http://localhost:8080/noop' This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking localhost (be patient) Completed 100 requests Completed 200 requests Finished 200 requests Server Software: CherryPy/3.2.0 Server Hostname: localhost Server Port: 8080 Document Path: /noop Document Length: 0 bytes Concurrency Level: 10 Time taken for tests: 0.564 seconds Complete requests: 200 Failed requests: 0 Write errors: 0 Total transferred: 27600 bytes HTML transferred: 0 bytes Requests per second: 354.58 [#/sec] (mean) Time per request: 28.202 [ms] (mean) Time per request: 2.820 [ms] (mean, across all concurrent requests) Transfer rate: 47.79 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 1.7 0 11 Processing: 6 26 23.5 24 248 Waiting: 3 25 23.6 23 248 Total: 6 26 23.4 24 248 Percentage of the requests served within a certain time (ms) 50% 24 66% 27 75% 29 80% 31 90% 34 95% 40 98% 51 99% 234 100% 248 (longest request) 

Qu'est-ce qui peut causer cela? La seule chose que je peux penser, c'est que nginx envoie des requêtes au backend dans un ordre différent de celui qu'ils sont arrivé, mais cela semble peu plausible.

La machine est une instance EC2 c1.medium avec 2 kernelx, CherryPy utilise un pool de threads avec 10 threads et nginx a worker_connections = 1024.

MISE À JOUR: deux autres résultats confus:

  • À une concurrency donnée, l'envoi de plus de requests améliore les performances. Avec une concurrency de 40 et 40 requests, j'ai un time médian de 3s et max 10.5s; avec une concurrency de 40 et 200 requests, j'ai une médiane de 38ms (!) et max 7.5s. En fait, le time total est inférieur à 200 requests! (6.5s vs. 7.5s pour 40). Tout ceci est répétitif.
  • La surveillance des deux process de travail nginx avec strace améliore considérablement leur performance, en prenant par exemple un time médian de 3s à 77ms, sans modifier sensiblement son comportement. (J'ai testé avec un appel API non sortingvial et j'ai confirmé que Strace ne modifie pas la réponse, ainsi que toutes ces observations de performances toujours en attente.) Ceci est également répété.

2 Solutions collect form web for “Le proxy inversé nginx augmente considérablement la latence du pire cas”

Le 3ème pire cas dans votre première course ab semble être une perte de packages. C'est probablement le résultat de certains buffers / ressources insuffisants configurés, certaines causes possibles dans aucun ordre particulier:

  • Une queue d'écoute trop petite sur un backend entraînant des débordements occasionnels de la file d'écoute (Linux est généralement configuré pour déposer simplement le package SYN dans ce cas, ce qui le rend indescriptible d'une perte de packages, voir netstat -s | grep listn pour savoir si c'est le problème ).
  • Un pare-feu statefull sur l'approche locale est la limite du nombre d'états et la suppression de certains packages SYN randoms en raison de cela.
  • Le système est hors socket / ports locaux en raison de sockets dans l'état TIME_WAIT, voir cette question si vous utilisez Linux.

Vous devez examiner votre operating system avec attention pour connaître la cause et configurer votre operating system en conséquence. Vous pouvez également suivre un guide de réglage du sous-système réseau pour votre operating system. Notez que EC2 pourrait être un peu spécifique ici, car il y avait des rapports sur des performances de réseau très limitées sur les instances EC2.

Du sharepoint vue de nginx, toute solution serait plus ou less mauvaise (car le problème n'est pas dans nginx, mais plutôt dans le operating system qui ne peut pas faire face à la charge et à la suppression des packages). Néanless, vous pouvez essayer quelques astuces pour réduire la charge sur le sous-système réseau du operating system:

  • Configurez les connections keepalive vers un backend .
  • Configurez le backend pour écouter sur un socket de domaine Unix (si votre backend le prend en charge), et configurez nginx en requêtes proxy.

NGINX utilise HTTP / 1.0 pour les connections de backend et n'a pas de keepalive par défaut (voir le lien dans la publication de Maxim pour backend keepalive), donc cela signifie faire une nouvelle connection de backend pour chaque request, augmentant légèrement la latence. Vous devriez probablement avoir plus de process de travail, 2 * le nombre de kernelx de CPU, avec un minimum de 5. Si vous avez plus de 10 requests simultanées, vous pourriez avoir besoin de plus de threads dans CherryPy.

  • Nginx en memory, ne charge-t-il pas de nouveaux vhosts?
  • Comment défendre le mieux contre une attaque DOS "slowloris" contre un server web Apache?
  • Le server Apache est surchargé à 30 requêtes / seconde, normal?
  • Elseif ne fonctionne pas sur Apache2.4
  • Combien d'users utilisent généralement le stream de mot de passe oublié?
  • Paramhe Apache Virtualhost
  • Devrais-je désactiver complètement le swap pour le serveur web linux?
  • Comment puis-je suivre quelle page est demandée en utilisant VirtualHost multiple dans Apache?
  • Serveurs individuels ou cluster
  • Comment publier un service Web sur Internet
  • Nom de domaine avec une input à x.xxxxx.com?
  • Les astuces du serveur de linux et windows, tels que ubuntu, centos, apache, nginx, debian et des sujets de rĂ©seau.