keep-alive connection cause download hangs in Nginx after 0.7.67
Slash
nginx-forum at nginx.us
Fri Jun 24 18:40:07 MSD 2011
Greetings,
I had the exact same issues you are describing. I use nginx to reverse
proxy to an application server backend running Windows+Apache+PHP. If
keepalive_timeout was non-zero, PDF downloads would hang on our website.
If we set it to zero, everything worked perfectly. However, we run all
our sites on SSL exclusively; The overhead of doing SSL Negotiation for
every single HTTP request was hurting performance significantly.
I noticed that the length of "hang" of the download was directly
proportional to the value of keepalive_timeout. If the keepalive was set
to 60, it would take 60 seconds before the download appeared to
"finish". If it was 75, it appeared to the client that the download took
75 seconds.
When inspecting the headers for the PDF response, I realized the issue.
"Content-Encoding: gzip". Why is this an issue? Because when the
"Content-Length" header is computed on the backend in PHP, it is
computing the length BEFORE it was gzipped. So, there is a difference
between the "Content-Length" and the size of what is actually sent to
the client. The actual amount of data sent to the client was gzipped,
and SMALLER than the "Content-Length" header.
In my case, PHP had zlib.output_compression set to "On", which
compressed and altered the size of the PDF, making it smaller.
Therefore, the client was waiting for data that wasn't there. The client
received all the data, but didn't know it. It was waiting for the
additional bytes. When the connection timed out (keepalive_timeout), it
finally "finished" successfully (although the client already had 100% of
the data).
When keepalive_timeout was 0, nginx would close the connection
immediately because nginx knew the request was complete- regardless of
what Content-Length says- thus signalling the client to stop waiting for
additional data.
I would suggest making sure the data sent to the client is actually
equal to what the "Content-Length" header says. Your application code
could be inadvertently compressing it (like PHP was doing for me) or
your backend webserver could be doing it (like Apache). I turned zlib
compression Off in php.ini on my application server, let nginx do gzip
for HTML data (nothing is modifying the PDFs anymore), and it completely
resolved the issue. My keepalive_timeout is set to 60 and performance
has improved dramatically since we eliminated countless SSL Negotiation
steps.
Hope this helps!
Posted at Nginx Forum: http://forum.nginx.org/read.php?2,170139,209671#msg-209671
More information about the nginx
mailing list