问题描述
我有一个带有对象服务器的数组,如下所示:
I have an array with object server like this:
Array
(
[0](
(
[id] => 1
[version] => 1
[server_addr] => 192.168.5.210
[server_name] => server1
)
)
[1](
(
[id] => 2
[server_addr] => 192.168.5.211
[server_name] => server2
)
)
)
通过运行以下代码,我可以获得所需的输出
By running the code below, I'm able to get the desired output
foreach ($model as $server) {
$cpu_usage = shell_exec('sudo path/to/total_cpu_usage.sh '.$server->server_addr);
$memory_usage = shell_exec('sudo path/to/total_memory_usage.sh '.$server->server_addr);
$disk_space = shell_exec('sudo path/to/disk_space.sh '.$server->server_addr);
$inode_space = shell_exec('sudo path/to/inode_space.sh '.$server->server_addr);
$network = shell_exec('sudo path/to/network.sh '.$server->server_addr);
exec('sudo path/to/process.sh '.$server->server_addr, $processString);
$processArray = array();
foreach ($processString as $i) {
$row = explode(" ", preg_replace('/\s+/', ' ', $i));
array_push($processArray,$row);
}
$datetime = shell_exec('sudo path/to/datetime.sh '.$server->server_addr);
echo $cpu_usage;
echo $mem_usage;
echo $disk_space;
......
}
我的脚本类似于:
#!/bin/bash
if [ "$1" == "" ]
then
echo "To start monitor, please provide the server ip:"
read IP
else
IP=$1
fi
ssh root@$IP "date"
但是5台服务器的整个过程花费了10秒钟,而1台服务器的花费不到2秒钟.这是为什么?反正有减少时间的地方吗?我的猜测是exec命令在进入下一个循环之前正在等待将输出分配给变量?我试着用Google搜索一点,但是大多数答案都是针对的,根本没有返回任何输出...尽管我需要输出
But the whole process took like 10 sec for 5 servers compared to 1 server for less than 2 sec. Why is that? Is there anyway to lessen the time? My guess is that the exec command was waiting for the output to be assign to the variable before going to next loop? I tried to google a little bit but most of the answer are for without returning any output at all... I need the output though
推荐答案
您可以同时使用popen()
运行脚本,并稍后使用fread()
捕获输出.
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);
我测试了类似的代码来执行5个脚本,它们休眠了2秒钟,整个过程只花了2.12秒钟而不是使用shell_exec()
的10.49秒.
I tested a similar code to execute 5 scripts that sleep for 2 seconds and the whole thing took only 2.12 secondsinstead of 10.49 seconds with shell_exec()
.
更新1:非常感谢 Markus AO 指出了优化潜力.
Update 1: Big thanks to Markus AO for pointing out an optimization potential.
更新2::修改了代码,以消除覆盖的可能性.结果现在在$model
内部.
Update 2: Modified the code to remove the possibility of overwrite.The results are now inside $model
.
这也可以显示哪个服务器拒绝了连接,以防有关sshd的问题影响到您.
This can also show which server refused the connection, in case that issue about sshd is affecting you.
这篇关于PHP同时运行多个脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!