10 votos

¿Por qué los Cactus manténgase a la espera de muertos de sondeo procesos?

Actualmente estoy configurando un nuevo Debian (6.0.5) del servidor. Me puse Cactus (0.8.7 g) en el ayer y han estado luchando con él desde entonces.

Emisión inicial

La primera cuestión que me estaba observando, era que a mi los gráficos no eran de la actualización. Así que he comprobado mi cacti.log y encontré este respecto mensaje:

POLLER: Poller[0] Maximum runtime of 298 seconds exceeded. Exiting.

Que no puede ser bueno, ¿verdad? Así que me fui comprobando y comenzó poller.php mí mismo (a través de la sudo -u www-data php poller.php --force). Se va a la bomba de un montón de mensajes (que todo parezca lo que sería de esperar) y, a continuación, cuelgue por un minuto. Después de 1 minuto, que se repetirá el siguiente mensaje:

Waiting on 1 of 1 pollers.

Esto se prolonga durante 4 minutos más hasta que el proceso se fuerza terminado para la ejecución de más de 298s.

Tan lejos y tan bien

Me fui para una buena hora tratando de determinar qué sondeo todavía estén en ejecución, hasta que llegué a la conclusión de que simplemente no es la ejecución de sondeo.

La depuración

Me registré poller.php para ver cómo esa advertencia se emite y por qué. En línea 368, Cactus recuperará el número de terminado de los procesos de la base de datos y utilizar ese valor para calcular cuántos procesos están aún en marcha. Así que, vamos a ver que valor!

He añadido el siguiente código de depuración en poller.php:

$finished_processes = db_fetch_cell("SELECT count(*) FROM cacti.poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00'");
print "Finished: " . $finished_processes . " - Started: " . $started_processes . "\n";

Resultado

Esto imprimirá la siguiente dentro de un segundo de partida poller.php:

Finished: 0 - Started: 1
Waiting on 1 of 1 pollers.
Finished: 1 - Started: 1

Por lo que los valores se leen y son válidos. Hasta que llegamos a la parte en donde se mantiene un bucle:

Finished:  - Started: 1
Waiting on 1 of 1 pollers.

De repente, el valor se ha ido. Por qué? Poner var_dump() en no confirma el problema:

NULL
Finished:  - Started: 1
Waiting on 1 of 1 pollers.

El valor de retorno es NULL. ¿Cómo puede ser eso cuando se consultan SELECT COUNT()...? (SELECT COUNT() siempre debe devolver una fila de resultado, ¿no?)

Más de depuración

Así que me fui en lib\database.php y tenía una mirada en que db_fetch_cell(). Un poco de pruebas confirmado, que el conjunto de resultados está realmente vacía.

Así que he añadido a mi propia consulta de base de datos de código en allí para ver lo que iba a hacer:

$finished_processes = db_fetch_cell("SELECT count(*) FROM poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00'");
print "Finished: " . $finished_processes . " - Started: " . $started_processes . "\n";

$mysqli = new mysqli("localhost","cacti","cacti","cacti");
$result = $mysqli->query("SELECT COUNT(*) FROM poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00';");
$row = $result->fetch_assoc();
var_dump( $row );

Esta es la salida

Finished:  - Started: 1
array(1) {
  ["COUNT(*)"]=>
  string(1) "2"
}
Waiting on 1 of 1 pollers.

Así, los datos están ahí y se puede acceder sin problemas, no sólo con el método de Cactus está utilizando?

Compruebe que no!

Yo habilitado MySQL registro para asegurarse de que no estoy imaginando cosas. Efectivamente, cuando el mensaje de error es un bucle, el cacti.log lee como si se consulta como un loco:

06/29/2012 08:44:00 PM - CMDPHP: Poller[0] DEVEL: SQL Cell: "SELECT count(*) FROM cacti.poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00'"
06/29/2012 08:44:01 PM - CMDPHP: Poller[0] DEVEL: SQL Cell: "SELECT count(*) FROM cacti.poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00'"
06/29/2012 08:44:02 PM - CMDPHP: Poller[0] DEVEL: SQL Cell: "SELECT count(*) FROM cacti.poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00'"

Pero ninguna de estas consultas se registran por MySQL. Sin embargo, cuando añado mi propia consulta de base de datos de código, se muestra igual de bien.

enter image description here
haga click para agrandar


¿Qué diablos está pasando aquí?

Cavar más profundo...

Llegué a la conclusión de que la conexión de base de datos debe estar perdido en algún lugar en el proceso y adodb simplemente no le importa.

Así que después de un poco de cavar alrededor, finalmente se coloca el mensaje de depuración en drivers/adodb-mysql.inc.php, en línea 529, en la _close función. Yo quería ver cuando se cierra la conexión.

Yo en realidad (por fin), se convirtió en PHP depuración y se dio cuenta de mysql_query() fue llamado con un booleano id de conexión (un indicador de un intencionalmente conexión cerrada).

// returns true or false
function _close()
{
    @mysql_close($this->_connectionID);
    echo "!!!! CLOSED !!!!\n";
    debug_print_backtrace();
    $this->_connectionID = false;
}

Lo que hace que la impresión?

oliver@j27773:/etc/php5/conf.d$ sudo -u www-data php /usr/share/cacti/site/poller.php --force
06/30/2012 01:33:49 AM - POLLER: Poller[0] NOTE: Poller Int: '60', Cron Int: '300', Time Since Last: '61', Max Runtime '298', Poller Runs: '5'
06/30/2012 01:33:49 AM - POLLER: Poller[0] DEBUG: About to Spawn a Remote Process [CMD: /usr/bin/php, ARGS: -q "/usr/share/cacti/site/cmd.php" 0 3]
Finished: 0 - Started: 1
Waiting on 1 of 1 pollers.
Finished: 1 - Started: 1
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_apache_sb_keepalive_100.rrd --template apache_sb_keepalive 1341012829:0
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_apache_reqpersec_95.rrd --template apache_reqpersec 1341012829:.0228409
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_apache_bytesperreq_90.rrd --template apache_bytesperreq 1341012829:13925.7
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_cpu_85.rrd --template cpu 1341012829:1
OK u:0.00 s:0.00 r:1.00
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_hdd_used_80.rrd --template hdd_used:hdd_total 1341012829:924741632:2677886976
OK u:0.00 s:0.00 r:1.00
OK u:0.00 s:0.01 r:1.00
OK u:0.00 s:0.01 r:1.00
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_apache_sb_wait_105.rrd --template apache_sb_wait 1341012829:9
OK u:0.00 s:0.01 r:1.00
OK u:0.00 s:0.01 r:1.00
06/30/2012 01:33:50 AM - SYSTEM STATS: Time:1.1261 Method:cmd.php Processes:1 Threads:N/A Hosts:2 HostsPerProcess:2 DataSources:7 RRDsProcessed:6
Loop  Time is: 1.1291718482971
Sleep Time is: 58.867464065552
Total Time is: 1.1325359344482
!!!! CLOSED !!!!
#0  ADODB_mysql->_close() called at [/usr/share/php/adodb/adodb.inc.php:2141]
#1  ADOConnection->Close() called at [/usr/share/cacti/site/lib/database.php:68]
#2  db_close() called at [/usr/share/cacti/site/poller.php:455]
^C06/30/2012 01:33:55 AM - CMDPHP: Poller[0] WARNING: Cacti Master Poller process terminated by user

Y ahora estoy demasiado cansado para investigar...

5voto

Peter Carlos Puntos 428

Me hizo investigar un poco más y se dio cuenta de que el cierre de la conexión a la base de datos es intencional. La conexión debe ser restablecida para el siguiente sondeo de ejecución. Pero no lo es.

He aquí un extracto de poller.php:

if ($poller_runs_completed < $poller_runs) {
    db_close();
    // Debug message by myself
    echo "RECONNECTING IN " . $sleep_time . "\n";
    usleep($sleep_time * 1000000);
    db_connect_real($database_hostname, $database_username, $database_password, $database_default, $database_type, $database_port);
}

También comprobé db_connect_real y es, de hecho, llamado después de la usleep completa. Así que voy a seguir cavando.

Por el momento, he modificado la sección como esta:

if ($poller_runs_completed < $poller_runs) {
    //db_close();
    // Debug message by myself
    echo "RECONNECTING IN " . $sleep_time . "\n";
    usleep($sleep_time * 1000000);
    //db_connect_real($database_hostname, $database_username, $database_password, $database_default, $database_type, $database_port);
}

Ahora el sondeo se ejecuta sin ninguna advertencia, y los gráficos están en proceso de elaboración. Sin embargo, todavía hay un problema. No todos los de mi gráficos se dibujan correctamente, como se puede ver en la siguiente imagen:

A rendered graph showing the results from the workaround
haga click para agrandar


Supuse que esto es debido a que el sondeo corriendo muy rara vez para ciertas fuentes de datos. Para solucionar esto, he cambiado a la columna vertebral (que yo quería hacer de todos modos) y configurarlo para utilizar 4 hilos.

Cacti poller configuration

Tan lejos, tan buena...

Actualización

Me clavaron profundamente en este tema y pensé que me había fijado. Supuse que la conexión no se almacena correctamente después de que el intento de volver a conectar el sondeo.

Mi intento de resolver que parecía prometedor, pero los gráficos resultantes todavía estaban defectuosos. Así que el problema es más profundo.

La solución que he desarrollado anteriormente y se presentan en esta respuesta todavía funciona perfectamente. He decidido no invertir más tiempo en este tema y quedarse con la solución. Lo siento.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: