Un grand contenu Nginx / uwsgi-served est bloqué pour les secondes de keepalive_timeout

Je sers un pdf généré dynamicment à travers django 1.5.1 en utilisant une vue comme:

pdf = generate_pdf() response = HttpResponse(pdf, mimetype="application/pdf") response['Content-Disposition'] = 'attachment; filename=1234_2013_10_30.pdf' return response 

Fonctionne 100% du temps sur le serveur de développement. Cependant, j’utilise la version 1.9.18.2 et la version 1.1.19 de uwsgi et j’obtiens le comportement suivant:

 $ curl -v -o test.out "http://localhost/demo/awc.pdf?submissionType=addition&permit=1234" ... * Connected to localhost (127.0.0.1) port 80 (#0) > GET /demo/awc.pdf?submissionType=addition&permit=1234 HTTP/1.1 > User-Agent: curl/7.21.2 (Windows) libcurl/7.21.2 OpenSSL/1.0.0a zlib/1.2.3 > Host: localhost > Accept: */* > 0 0 0 0 0 0 0 0 --:--:-- 0:00:10 --:--:-- 0 < HTTP/1.1 200 OK < Server: nginx/1.1.19 < Date: Wed, 30 Oct 2013 22:14:23 GMT < Content-Type: application/pdf < Transfer-Encoding: chunked < Connection: keep-alive < Vary: Accept-Language, Cookie < Content-Language: en-us < Content-Disposition: attachment; filename=1234_2013_10_30.pdf < { [data not shown] 100 2313k 0 2313k 0 0 270k 0 --:--:-- 0:00:12 --:--:-- 0 ..... 100 2313k 0 2313k 0 0 77452 0 --:--:-- 0:00:30 --:--:-- 0* transfer closed with outstanding read data remaining 100 2313k 0 2313k 0 0 75753 0 --:--:-- 0:00:31 --:--:-- 0* Closing connection #0 curl: (18) transfer closed with outstanding read data remaining 

En résumé, le client reçoit une réponse en 10 secondes, télécharge toutes les données en 2 secondes environ, puis se bloque pendant 18 secondes supplémentaires.

Ce n’est pas un hasard si ma configuration nginx spécifie keepalive_timeout 20s; . Après avoir attendu keepalive_timeout secondes, le contenu est parfaitement correct. Je peux “résoudre” le problème en définissant keepalive_timeout à zéro mais ce n’est pas vraiment une solution viable.

Lorsque le contenu est petit (moins de ~ 1 Mo), le problème disparaît inexplicablement.

 > GET "http://localhost/demo/awc.pdf?submissionType=addition&permit=5678" HTTP/1.1 > User-Agent: curl/7.21.2 (Windows) libcurl/7.21.2 OpenSSL/1.0.0a zlib/1.2.3 > Host: localhost > Accept: */* > 0 0 0 0 0 0 0 0 --:--:-- 0:00:04 --:--:-- 0< HTTP/1.1 200 OK < Server: nginx/1.1.19 < Date: Wed, 30 Oct 2013 22:39:12 GMT < Content-Type: application/pdf < Transfer-Encoding: chunked < Connection: keep-alive < Vary: Accept-Language, Cookie < Content-Language: en-us < Content-Disposition: attachment; filename=1234_2013_10_30.pdf < { [data not shown] 100 906k 0 906k 0 0 190k 0 --:--:-- 0:00:04 --:--:-- 246k* Connection #0 to host localhost left intact 

Je suppose que cela a quelque chose à voir avec l’encodage en bloc ou le manque d’en-tête de longueur du contenu, mais je n’arrive pas à trouver l’incantation magique. Des idées?

Toujours pas sûr pourquoi le problème d’origine se produit, mais trouvé une solution de rechange décente:

Désactiver le codage de transfert en blocs dans la configuration nginx semble éviter le problème.

 location / { uwsgi_pass unix:///var/run/uwsgi/app/socket; include uwsgi_params; # keepalive_timeout 0; chunked_transfer_encoding off; } 

J’avais le même problème mais cela ne se produisait que sur du contenu généré dynamicment. Je suis sur nginx 1.5.8 et Ubuntu 12.04LTS exécutant un fastcgi_pass à php-fpm – et mon keepalive_timeout provoquait également le blocage!

Je pense que keepalive_timeouts est seulement (supposé?) Utilisé pour du contenu statique – mais je trompe mon fichier javascript dynamic (js.php) comme s’il était statique pour que le timeout de keepalive soit appliqué?

Si je peux trouver une solution permanente par opposition à cette explication … je la posterai. Ah oui, c’est peut-être la réponse, où il est dit de spécifier ceci dans le fichier nginx.conf –

 fastcgi_keep_conn on; 

J’ai quand même laissé mon keepalive_timeout à seulement 1 seconde, mais la solution fournie dans cette réponse acceptée a du sens – mon fichier dynamic était passé à fastcgi mais la connexion keepalive n’a pas été retenue par fastcgi – ici aussi un document officiel nginx .

Par défaut, un serveur FastCGI ferme une connexion juste après l’envoi de la réponse. Cependant, lorsque cette directive est définie sur la valeur on, nginx demandera à un serveur FastCGI de garder les connexions ouvertes. Cela est nécessaire, en particulier, pour que les connexions keepalive aux serveurs FastCGI fonctionnent.