Почему Cacti продолжает ждать мертвых процессов poller?


11

В настоящее время я настраиваю новый сервер Debian (6.0.5). Я вчера положил на нее Cacti (0,8,7 г) и с тех пор борюсь с ней.

Первоначальный выпуск

Первоначальная проблема, которую я наблюдал, заключалась в том, что мои графики не обновлялись. Поэтому я проверил cacti.logи нашел это относительно сообщения:

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

Это не может быть хорошо, верно? Так что я пошел проверять и начал poller.phpсебя (через sudo -u www-data php poller.php --force). Он выдаст много сообщений (которые выглядят так, как я ожидал), а затем зависнет на минуту. По истечении 1 минуты будет зациклено следующее сообщение:

Waiting on 1 of 1 pollers.

Это продолжается еще 4 минуты, пока процесс не будет принудительно завершен для работы дольше 298 с.

Все идет нормально

Я продолжал добрый час, пытаясь определить, какой поллер еще может работать, пока не пришел к выводу, что бегущего поллера просто нет .

Отладка

Я проверил, poller.phpкак выдается это предупреждение и почему. В строке 368 Cacti извлекает количество завершенных процессов из базы данных и использует это значение для расчета количества процессов, которые еще выполняются. Итак, давайте посмотрим, что значение!

Я добавил следующий код отладки в 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";

Результат

В течение секунды после запуска будет напечатано следующее poller.php:

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

Значения читаются и являются действительными. Пока мы не доберемся до той части, где он продолжает цикл:

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

Внезапно ценность исчезла. Почему? Размещение var_dump()там подтверждает проблему:

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

Возвращаемое значение NULL. Как это может быть при запросе SELECT COUNT()...? ( SELECT COUNT()всегда должен возвращать одну строку результата, не так ли?)

Больше отладки

Так что я вошел lib\database.phpи посмотрел на это db_fetch_cell(). Небольшое тестирование подтвердило, что набор результатов фактически пуст.

Поэтому я добавил свой собственный код запроса к базе данных, чтобы посмотреть, что это будет делать:

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

Это будет выводить

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

Итак, данные есть и могут быть доступны без проблем, только не с помощью метода, который использует Cacti?

Дважды проверьте это!

Я включил ведение журнала MySQL, чтобы убедиться, что я не воображаю вещи. Конечно же, когда сообщение об ошибке зациклено, cacti.logчтение выглядит так, как будто оно запрашивает, как безумный:

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

Но ни один из этих запросов не регистрируется MySQL. Тем не менее, когда я добавляю свой собственный код запроса к базе данных, он обнаруживается просто отлично.

введите описание изображения здесь
нажмите, чтобы увеличить

Какого черта здесь происходит?

Копать глубже...

Я пришел к выводу, что соединение с базой данных должно быть потеряно где-то в процессе, и adodb просто не волнует.

Поэтому, немного покопавшись, я наконец поместил отладочное сообщение в drivers/adodb-mysql.inc.phpстроку 529 в _closeфункцию. Я хотел видеть, когда соединение закрыто.

Я фактически (наконец) включил отладку PHP и понял, что mysql_query()вызывается с логическим идентификатором соединения (индикатор намеренно закрытого соединения).

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

Что это печатает?

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

И теперь я слишком устал, чтобы расследовать это ...

Ответы:


6

Я продолжил расследование и понял, что закрытие соединения с базой данных является намеренным. Соединение должно быть восстановлено для следующего запуска опроса. Но это не так.

Вот выдержка из 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);
}

Я также проверил, db_connect_realи это, на самом деле, называется после usleepзавершения. Так вот, где я буду продолжать копать.

В настоящее время я изменил раздел следующим образом:

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

Теперь программа опроса работает без каких-либо предупреждений, и мои графики рисуются. Тем не менее, есть еще проблема. Не все мои графики нарисованы правильно, как видно из следующего изображения:

Визуализированный график, показывающий результаты обходного решения
нажмите, чтобы увеличить

Я предположил, что это связано с тем, что опросщик запускается слишком редко для определенных источников данных. Чтобы решить эту проблему, я переключился на позвоночник (что я в любом случае хотел сделать) и настроил его на использование 4 потоков.

Конфигурация Cacti Poller

Все идет нормально...

Обновить

Я углубился в эту проблему и подумал, что решил ее. Я предположил, что соединение не сохранено должным образом после попытки восстановления соединения.

Сначала моя попытка решить эту проблему выглядела многообещающей, но полученные графики все еще были ошибочными. Так что проблема кроется глубже.

Обходной путь, который я разработал ранее и представил в этом ответе, все еще работает отлично. Я решил не тратить больше времени на эту проблему и остаться с обходным путем. Сожалею.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.