I have a scheduled task that runs a script on a regular basis (every hour). This script does some heavy interaction with the database and filesystem and regularly takes several minutes to run. The problem is, the server's cpu-usage spikes while the script is running and slows down normal operations. Is there a way to throttle this process so that it takes longer but does not consume as many resources?
I've looked at different configuration options for PHP but there does not appear to be any that fit my needs.
Setting memory_limit in php.ini to something lower causes my data objects to overflow quite easily.
I've seen similar posts where people suggested using sleep() at certain points in the script but that does not prevent the script from spiking the server.
The optimal solution would be some way to tell the Lamp (in this case Wamp) stack to only use 10% max cpu utilization. I'm not concerned at all about runtime and would prefer that it take longer if it means saving cpu cycles per second. My alternate solution would be to setup a different server with database replication so the cron could go to town without slowing everything else down.
Environment: Windows Server 2k3, Apache 2.2.11, PHP 5.2.9, MySQL 5.1
I appreciate any insight to this situation.
EDIT: I appreciate all the answers, even the ones that are *nix-specific. It's still early enough in my situation to change the hosting environment. Hopefully this question will help others out regardless of the OS.
For allowing to run the script forever and ignore user aborts, set PHP inbuilt function ignore_user_abort(true). By default, it set to False which throws fatal error when client aborts to stop the script.
Re: What is the maximum http request per second Everything can handler ? The HTTP server should be able to handle 10,000 requests per second. Above that, you will likely run into winsock2 limitations. There is a db query behind each request, so the limit is more realistically around 100-1000 requests per second.
This is a tricky problem. If you're running the PHP script via the command line, you can set the process's scheduling priority to low (start /low php.exe myscript.php
I believe). If your PHP script itself is actually doing most of the processing that's eating your CPU, this might work. However, you said you are doing some heavy database and filesystem interaction, which this solution will not help. It looks like there is a MySQL hint "LOW_PRIORITY" for INSERT and UPDATE queries that may help you there, but I have not tried those.
You can set processes in Windows to be a lower priority. I'm not sure how the process is being kicked off, but if you set the process to be a low priority, whatever wants CPU resources will get them if you set the priority to be really low.
In UNIX (LAMP) I managed to solve the problem by checking the load of the server before continuing the loop
function get_server_load($windows = 0) {
$os = strtolower(PHP_OS);
if(strpos($os, "win") === false) {
if(file_exists("/proc/loadavg")) {
$load = file_get_contents("/proc/loadavg");
$load = explode(' ', $load);
return $load;
}
elseif(function_exists("shell_exec")) {
$load = explode(' ', `uptime`);
return $load;
}
else {
return "";
}
}
}
for(... ... ...){
$data = get_server_load();
if($data[0] < 0.2){
// continue
}else{
sleep(1);
}
}
This function should work also on windows but I can't guarantee it. On linux it gives you back an array with the load of the last 1 minute, 5 minutes and 15 minutes
Also, consider to start your scripts (if by CLI) with a lower priority (in Linux, use "nice")
You can also use other values before continuing the loop, like the number of Apache active processes (you can parse the page 127.0.0.1/server_status?auto if you enabled the mod_status in httpd.conf), or also the MySQL situation (active connections?)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With