para - paginas php ejemplos
PHP ejecuta mĂșltiples scripts al mismo tiempo (4)
Tengo una matriz con servidor de objetos como este:
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
)
)
)
Al ejecutar el siguiente código, puedo obtener la salida deseada
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;
......
}
Mis scripts son similares a:
#!/bin/bash
if [ "$1" == "" ]
then
echo "To start monitor, please provide the server ip:"
read IP
else
IP=$1
fi
ssh root@$IP "date"
Pero todo el proceso tomó 10 segundos para 5 servidores en comparación con 1 servidor durante menos de 2 segundos. ¿Porqué es eso? ¿Hay alguna forma de disminuir el tiempo? ¿Supongo que el comando exec estaba esperando que se asignara la salida a la variable antes de pasar al siguiente ciclo? Intenté googlear un poco, pero la mayoría de las respuestas son sin devolver ninguna salida ... Necesito la salida, aunque
No sé cómo hacer que tu lógica sea más rápida, pero puedo decirte cómo utilizo para rastrear el tiempo de ejecución cuando tengo scripts. Al comienzo del script, coloque var $start = date(''c'');
y al final solo echo '' start=''.$start; echo '' end=''.date(c);
simple echo '' start=''.$start; echo '' end=''.date(c);
echo '' start=''.$start; echo '' end=''.date(c);
Todo lo que necesita hacer es agregar un > /dev/null &
al final en Linux, pero no obtendrá el resultado, pero se ejecutará como un proceso en segundo plano (asincrónico).
shell_exec(''sudo path/to/datetime.sh ''.$server->server_addr.'' > /dev/null &'');
vea también este script de proceso en segundo plano de mi GitHub, (tiene procesos de fondo compatibles con Windows)
https://github.com/ArtisticPhoenix/MISC/blob/master/BgProcess.php
¡Aclamaciones!
Puede ejecutar sus scripts simultáneamente con popen()
y tomar el resultado más tarde con 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);
Probé un código similar para ejecutar 5 scripts que duermen durante 2 segundos y todo llevó solo 2.12 segundos en lugar de 10.49 segundos con shell_exec()
.
Actualización 1: Muchas gracias a Markus AO por señalar un potencial de optimización.
Actualización 2: se modificó el código para eliminar la posibilidad de sobrescribir. Los resultados están ahora dentro de $model
.
Esto también puede mostrar qué servidor rechazó la conexión, en caso de que el problema con sshd lo afecte.
Sí, estás en lo cierto: tu script PHP está esperando cada respuesta antes de continuar.
Supongo que esperas ejecutar las solicitudes a todos los servidores simultáneamente, en lugar de esperar a que cada servidor responda. En ese caso, suponiendo que estés ejecutando una versión de PHP sin hilos, mira en pthreads . Una opción es usar cURL multi-exec para realizar solicitudes asincrónicas. Luego también está pcntl_fork que puede ayudarte. También vea este y este hilo para posibles enfoques de subprocesamiento / asincronización.
Aparte de eso, prueba y compara los scripts de shell individualmente para ver dónde están los cuellos de botella y si puedes acelerarlos. Eso puede ser más fácil que las configuraciones de subprocesos / asincronías en PHP. Si tiene problemas con la latencia de la red, escriba un script de shell agregador que ejecute los otros scripts y devuelva los resultados en una sola solicitud, y solo los invoque en su script PHP.