PHP running multiple scripts concurrently

◇◆丶佛笑我妖孽 提交于 2019-12-04 07:09:52
Rei

You can run your scripts simultaneously with popen() and grab the output later with fread().

//execute
foreach ($model as $server) {
    $server->handles = [
        popen('sudo path/to/total_cpu_usage.sh '.$server->server_addr, 'r'),
        popen('sudo path/to/total_memory_usage.sh '.$server->server_addr, 'r'),
        popen('sudo path/to/disk_space.sh '.$server->server_addr, 'r'),
        popen('sudo path/to/inode_space.sh '.$server->server_addr, 'r'),
        popen('sudo path/to/network.sh '.$server->server_addr, 'r'),
    ];
}

//grab and store the output, then close the handles
foreach ($model as $server) {
    $server->cpu_usage = fread($server->handles[0], 4096);
    $server->mem_usage = fread($server->handles[1], 4096);
    $server->disk_space = fread($server->handles[2], 4096);
    $server->inode_space = fread($server->handles[3], 4096);
    $server->network = fread($server->handles[4], 4096);

    foreach($server->handles as $h) pclose($h);
}

//print everything
print_r($model);

I tested a similar code to execute 5 scripts that sleep for 2 seconds and the whole thing took only 2.12 seconds instead of 10.49 seconds with shell_exec().

Update 1: Big thanks to Markus AO for pointing out an optimization potential.

Update 2: Modified the code to remove the possibility of overwrite. The results are now inside $model.

This can also show which server refused the connection, in case that issue about sshd is affecting you.

I don't know how to make your logic faster but I can tell you how I use to track time of running when I have scripts. At the begin of the script put some var $start = date('c'); and at the end just simple echo ' start='.$start; echo ' end='.date(c);

Markus AO

Yes you're correct: your PHP script is waiting for each response before moving onward.

I presume you're hoping to run the requests to all servers simultaneously, instead of waiting for each server to respond. In that case, assuming you're running a thread-safe version of PHP, look into pthreads. One option is to use cURL multi-exec for making asynchronous requests. Then there's also pcntl_fork that may help you out. Also see this & this thread for possible thread/async approaches.

Aside that, do test and benchmark the shell scripts individually to see where the bottlenecks are, and whether you can speed them up. That may be easier than thread/async setups in PHP. If you have issues with network latency, then write an aggregator shell script that executes the other scripts and returns the results in one request, and only call that in your PHP script.

All you need to do is add an > /dev/null & at the end on Linux, you wont get the output though, but it will run as a background ( async ) process.

shell_exec('sudo path/to/datetime.sh '.$server->server_addr.'  > /dev/null &');

see also this Background process script from my GitHub, ( it has windows compatible background processes )

https://github.com/ArtisticPhoenix/MISC/blob/master/BgProcess.php

Cheers!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!