Я отношу себя к поколению "диких сетевиков", которые в начале века начинали строить сети различного масштаба на постсоветском пространстве. Не хватало всего - денег, образования, специалистов, оборудования ... Зато энтузиазма и самоуверенности было немерено. Лепили сети из чего попало, или из того на что хватало денег. Как сейчас помню тот день, когда купил свой первый L2 коммутатор - знаменитый DES-3526.

Естественно в какой-то момент происходит качественный рост, и появляется необходимость весь этот сетевой зоопарк мониторить. Методов и софта для мониторинга настолько много, что даже только их перечисление и краткие характеристики займут не одну статью.

Лет 5 назад я взялся переписать самописную NMS модулем в ABillS. Биллинг написан на Perl, а я на тот момент в нём был "нивзубногой". Документации по API биллинга мне хватило, чтобы перенести вебку с PHP на Perl. Поначалу для периодического опроса железок использовал аналог fping на Perl и отдельно снимал статистику по SNMP. Что больше всего раздражает при работе с SNMP - это жуткие лаги, и при росте количества опрашиваемых устройств, они также возрастают. Борются с этим разными методами: распараллеливание, увеличение таймаутов и прочее.

Собственно тут я хотел бы поделится своей реализацией SNMP опроса сетевого оборудования. Используется библиотека SNMP, которая является частью проекта Net-SNMP. Если честно, код работает по принципу "новичкам везет" (толерантный вариант "дуракам везет"). Скопировал код в каком-то мылолисте (ссылку не дам - не нашел), немного допилил для своих нужд, запустил и в первый момент даже не поверил глазам. Используемый мною на тот момент Observium опрашивал мою, не такую уж большую сетку (менее 300 коммутаторов) , больше минуты, причем в четыре потока (сразу замечу, что при опросе использовались минимум датчиков, иначе опрос мог растянутся и на 5 минут). А мой скрипт делал тоже самое за 8-10 секунд.

Ну и дальше сам код с комментариями:

use SNMP;

#Итак у нас есть массив из базы оборудования, пусть будет @obj_list.
my @obj_list = ('10.0.0.100', '10.0.0.101', '10.0.0.102');

#Задаем параметры, которые будем использовать при опросе.
my %snmpparms;
$snmpparms{Version}        = 2;
$snmpparms{Retries}        = 1;
$snmpparms{UseSprintValue} = 0;
$snmpparms{Community}      = 'public';#Надеюсь у Вас он не такой :)

#Для примера создаем массив из стандартных OID.
my @mibs;
        push @mibs, SNMP::Varbind->new( [ 'sysObjectID', 0 ] );
        push @mibs, SNMP::Varbind->new( [ 'sysName',     0 ] );
        push @mibs, SNMP::Varbind->new( [ 'sysLocation', 0 ] );

#Готовим варлист для опроса
my $vb = SNMP::VarList->new(@mibs);

sub nms_poll {
    
    foreach my $obj (@obj_list) {
        my $sess = SNMP::Session->new(
            %snmpparms,
            DestHost  => $obj,
        );
        $sess->get( $vb, [ \&nms_clb, $obj ] );

        &SNMP::MainLoop(2);
    }
    return 1 if $status;
    return undef;
}

#Ну и обратный вызов, где уже можно обработать полученные данные
sub nms_clb {
    my ( $obj, $vl ) = @_;
    #Тут проверяем, был ли мальчик
    if ( defined $vl->[0] ) {
        &SNMP::finish();
    }
    else {
        
    }

    return ();
}

За счет чего достигается такая разница в скорости опроса, мне не совсем понятно. Вот что пишет сам автор библиотеки про функцию SNMP::MainLoop:

to be used with async SNMP::Session calls. MainLoop must be called after initial async calls so return packets from the agent will not be processed. If no args suplied this function enters an infinite loop so program must be exited in a callback or externally interupted.

В заключение

Замечу что с обратными вызовами библиотека работает начиная с версии 5.04. Наверняка есть и другие "быстрые" варианты работы с SNMP, просто я с ними не сталкивался. Своим вариантом пользуюсь уже несколько лет и он меня вполне устраивает.

Написанное явно не тянет на статью, скорее заметка. Написал, потому что жалко пропадающих наработок, которые сейчас становятся не нужны. Время идет, мир меняется. Мелкие провайдеры банкротятся, поглощаются крупными игроками, переходят на агентские модели. В результате куча накопленного опыта попросту становится лишним. Думаю это не правильно :)