Perché i cactus continuano ad aspettare processi di poller morti?


11

Attualmente sto configurando un nuovo server Debian (6.0.5). Ieri ho messo i cactus (0.8.7g) e da allora ho combattuto con esso.

Problema iniziale

Il problema iniziale che stavo osservando era che i miei grafici non si stavano aggiornando. Quindi ho controllato il mio cacti.loge ho trovato questo messaggio relativo:

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

Non può essere buono, vero? Quindi sono andato a controllare e ho iniziato da poller.phpsolo (via sudo -u www-data php poller.php --force). Pomperà molti messaggi (che sembrano tutti come mi sarei aspettato) e poi si bloccherà per un minuto. Dopo quel 1 minuto, eseguirà il ciclo seguente del messaggio:

Waiting on 1 of 1 pollers.

Questo continua per altri 4 minuti fino a quando il processo termina forzatamente per l'esecuzione per più di 298 secondi.

Fin qui tutto bene

Sono andato avanti per un'ora cercando di determinare quale poller potrebbe essere ancora in esecuzione, fino a giungere alla conclusione che semplicemente non esiste poller in esecuzione .

Debug

Ho controllato poller.phpper vedere come viene emesso questo avviso e perché. Alla riga 368, Cacti recupererà il numero di processi finiti dal database e utilizzerà quel valore per calcolare quanti processi sono ancora in esecuzione. Quindi, vediamo quel valore!

Ho aggiunto il seguente codice di debug in 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";

Risultato

Questo stamperà quanto segue entro un secondo dall'inizio poller.php:

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

Quindi i valori vengono letti e sono validi. Fino a quando non arriviamo alla parte in cui continua il loop:

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

Improvvisamente, il valore è sparito. Perché? Inserirlo var_dump()conferma il problema:

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

Il valore di ritorno è NULL. Come può essere durante l'interrogazione SELECT COUNT()...? ( SELECT COUNT()dovrebbe sempre restituire una riga di risultato, non è vero?)

Più debug

Quindi sono entrato lib\database.phpe ho dato un'occhiata a quello db_fetch_cell(). Un po 'di test ha confermato che il set di risultati è effettivamente vuoto.

Quindi ho aggiunto il mio codice di query del database per vedere cosa farebbe:

$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 );

Questo produrrà

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

Quindi, i dati sono lì ed è possibile accedervi senza problemi, solo con il metodo Cacti?

Ricontrolla quello!

Ho abilitato la registrazione MySQL per assicurarmi di non immaginare cose. Abbastanza sicuro, quando il messaggio di errore è in loop, si cacti.loglegge come se stesse interrogando come un matto:

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'"

Ma nessuna di queste query è registrata da MySQL. Tuttavia, quando aggiungo il mio codice di query del database, si presenta bene.

inserisci qui la descrizione dell'immagine
clicca per ingrandire

Che diamine sta succedendo qui?

Scavando più a fondo...

Ho concluso che la connessione al database deve essere persa da qualche parte nel processo e adodb semplicemente non importa.

Quindi dopo un po 'di ricerche, ho finalmente inserito il messaggio di debug nella drivers/adodb-mysql.inc.phpriga 529 nella _closefunzione. Volevo vedere quando la connessione è chiusa.

In realtà (finalmente) ho attivato il debug di PHP e mi sono reso conto che mysql_query()veniva chiamato con un ID di connessione booleana (un indicatore di una connessione intenzionalmente chiusa).

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

Che cosa stampa?

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

E ora sono troppo stanco per investigare che ...

Risposte:


6

Ho approfondito un po 'di più e mi sono reso conto che la chiusura della connessione al database è intenzionale. La connessione deve essere ristabilita per la successiva esecuzione di polling. Ma non lo è.

Ecco un estratto da 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);
}

Ho anche controllato db_connect_realed è, in effetti, chiamato dopo il usleepcompletamento. Quindi è lì che continuerò a scavare.

Per il momento, ho modificato la sezione in questo modo:

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);
}

Ora il poller funziona senza avvertimenti e i miei grafici vengono disegnati. Tuttavia, c'è ancora un problema. Non tutti i miei grafici vengono disegnati correttamente, come si può vedere dalla seguente immagine:

Un grafico renderizzato che mostra i risultati della soluzione alternativa
clicca per ingrandire

Presumo che ciò sia dovuto al poller eseguito troppo raramente per determinate origini dati. Per risolverlo, sono passato al dorso (cosa che volevo fare comunque) e l'ho impostato per usare 4 thread.

Configurazione poller di cactus

Fin qui tutto bene...

Aggiornare

Ho approfondito questo problema e ho pensato di averlo risolto. Presumo che la connessione non sia stata correttamente memorizzata dopo il tentativo di riconnessione del poller.

Il mio tentativo di risolvere all'inizio sembrò promettente, ma i grafici risultanti erano ancora difettosi. Quindi il problema è più profondo.

La soluzione alternativa che ho sviluppato in precedenza e presentata in questa risposta funziona ancora perfettamente. Ho deciso di non investire altro tempo su questo problema e rimanere con la soluzione alternativa. Scusate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.