Trying to understand Apache timeout / architecture

apache-2.2timeout

I have a CentOS release 6.3 system running Apache httpd 2.2.15 and PHP 5.3.3.

My PHP web site is running fine except for one query, which has apparently hit a timeout limit. The query is now taking more than 60 seconds to run and, as a result, the users' browsers just sit waiting – for much longer, about 5 minutes or more – before showing a blank page.

It's made me wonder just how Apache/PHP works.

I set up a simple PHP script test case which simply does the following:

  • sleep for 55/65 seconds;
  • append "I'm still here!" to a file on the server;
  • output a line of HTML.

When the timeout is 55 seconds everything works as expected; my browser spins waiting for 55 seconds and then renders the HTML.

When I set the timeout to 65 seconds the browser spins for 5 minutes or more before showing a completely blank page. Meanwhile:

  • the "I'm still here" debug line is still appended to the file on the server, showing that the PHP happily ran;

  • the Apache access log also shows that the query ran, returning a HTTP status code of 200 and the correct number of bytes comprising the HTML;

  • there are no errors logged by either Apache or PHP.

I tried changing a couple of configuration settings that seemed relevant:

  • the Apache httpd.conf 'Timeout' directive, from 60 to 120;

  • the 'default_socket_timeout' setting for php.ini, from 60 to 120.

But the test case still ran exactly the same; the browser 'hanging' even after the page returns after 65 seconds. This is the case for several versions of Firefox.

Can someone assist me in understanding how things are working here? And, secondly, how I can increase the effective timeout limit so my slow query can take more than 60 seconds to run and successfully return its results to the browser?

I would have expected that, if there was a limit in Apache – "don't wait more than 60 seconds for PHP to run the query" – then it would either return some sort of error to the browser after that 60 seconds elapsed or otherwise log some other error. Instead I'm seeing the PHP run to completion, the Apache access log telling me "hey, everything went fine, I transmitted the 75 bytes of output to the browser", but the browser itself just sits there, never receiving that output. What is being silently 'disconnected'? If Apache never sends an error, and allows the PHP to run to completion, why doesn't it send the results back (like it says it does in its access log)?

Many thanks for any help.

Best Answer

Update all 60 second values in the /etc/php.ini to 120 to test. If you restarted Apache after the config changes, and still have a problem as described, then it appears that php is causing this based on the description.