Gary Punis Cuca Gary Punis Cuca - 1 year ago 97
PHP Question

How to avoid server irresponsive when a PHP script fails

I canĀ“t find an answer for this, probably I'm not searching with the right words.

When a PHP script fails (error in script, infinite loops, endless SQL calls, etc) the whole server goes "busy". It's like all the resources are taken and focus on trying to execute that script. By restarting apache/nginx the server goes back to normal.

How could this be avoided? Setting the timeout for the script won't solve it because if it's even 10 seconds timeout the server will be irresponsive for those 10 seconds to everybody.

Is there any way to avoid this happening? Yes, solving the script issues the problem will stop happening but I am sure there is a way to protect against this on the server side.

Just now an example comes to my mind. This script used to get the country code by calling a service in that website. For some reason the website would not serve to us randomly so the script would wait forever to receive the file contents.

$getcountry = file_get_contents('http://ip-api.com/php/'. getUserIP());


Thanks

Answer Source

Setting the timeout for the script won't solve it because if it's even 10 seconds timeout the server will be irresponsive for those 10 seconds to everybody.

Not if your server is set up properly. Setting the PHP timeout is the correct way to handle runaway scripts (aside from fixing the actual cause of the problem). Fatal script errors will terminate immediately and not take up server resources.

Your post seems to assume there is only one instance of a PHP script running at any time. This should not be the case. Your web server should be starting new process or threads, up to some set limit, for each web request handled by PHP. Or if you are using PHP-FPM, it's handed off to a pool of PHP processes to be handled. In no case should your whole server be locked up for one single request.

Now if your code or server has serious issues, then all requests may take too long and hang up further requests. The only solution is to fix the root of the problem and keep a reasonable timeout for as a failsafe.

For Apache these are some of the settings you will want to check: ServerLimit, StartServers, MaxClients. For PHP-FPM you would start with the max_children setting.

This script used to get the country code by calling a service in that website. For some reason the website would not serve to us randomly so the script would wait forever to receive the file contents.

This is a very common problem and must be accounted for by your code. You can never trust that a 3rd party service will return promptly. Obviously offloading requests such as this to background processes is best (e.g. crons). But if it needs to be done as part of a normal page request you should always set a reasonable timeout. For your specific example of using file_get_contents, reduce the socket timeout:

ini_set('default_socket_timeout', 10);  // 10 seconds
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download