Быстрый SNMP опрос сетевых устройств

    Я отношу себя к поколению "диких сетевиков", которые в начале века начинали строить сети различного масштаба на постсоветском пространстве. Не хватало всего - денег, образования, специалистов, оборудования ... Зато энтузиазма и самоуверенности было немерено. Лепили сети из чего попало, или из того на что хватало денег. Как сейчас помню тот день, когда купил свой первый 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, просто я с ними не сталкивался. Своим вариантом пользуюсь уже несколько лет и он меня вполне устраивает.

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

    Похожие публикации

    Средняя зарплата в IT

    120 000 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 9 172 анкет, за 1-ое пол. 2021 года Узнать свою зарплату
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 7

      0
      Посмотрите AnyEvent::SNMP — я использую его.
        0
        AnyEvent конечно замечательная штука, я сейчас ловлю SNMP-трапы с помощью этой либы. Но когда я писал этот скрипт, мои познания в перл были на уровне «никакой», и AnyEvent для меня был, что-то вроде тригонометрии для первоклассника. А сейчас уже смысла не вижу переписывать, и так все устраивает. И да, в моем случае даже не нужно ничего доустанавливать, библиотека идет в комплекте с net-snmp.
        0
        Спасибо за статью, очень интересно. В свое время нашел github.com/mteg/braa Насколько хтонично, настолько и интересная реализация, просто ураган.
          0

          Спасибо за статью. Я мониторю "Кактусом", мои самописные скрипты на bash и это жесть, когда начинаются задержки и подтормаживания - в сетке около 100 железок, некоторые не бьются по mib-ам и потому для них всё исключительно самописное и значит тормозное (процессор Carl в промышленных кондиционерах выдаёт свои параметра в виде 3х производных таблиц, расстановка значений в которых зависит от фантазии программмстов конкретной железки - у меня 3 разных кондея и у каждого всё по своему и большая удача, если есть таблица соответствия значения и номера ячейки не говоря уже о трапах/алармах). Попробую ваш скрипт себе прикрутить - надеюсь будет поменьше тормозов и подвисов, чем в стандартном snmpwalk ....

            0
            Вообще, SNMP.pm фактически использует тот же программный код, что и snmpwalk. Тут снижение времени опросов достигается как раз на большом количестве устройств за счет использования &SNMP::MainLoop. С MIB отдельная история, практически все базы от вендоров приходится исправлять. Сейчас как раз пишу статью про MIB браузер, постараюсь привести несколько примеров.
            0
            Скорость сбора данных по snmp зависит не столько от того, кто запрашивает и как на нем это реализовано, сколько от отвечающего девайса. Упомянутый вами Observium на моем опыте за 10 секунд снимает с каталиста-шеститонника порядка тысячи OID-ов, а со свитчей доступа намного более дебильных производителей типа господи прости д-линка, с каждого может мучаться с десятью цифрами до минуты в зависимости от настроения коммутатора. А код ваш быстро работает, потому что, вот же положила, сам автор написал использует асинхронные вызовы и, таким образом, не ожидает ответа с той стороны для совершения следующей итерации. Все бы хорошо, но есть далеко ненулевая вероятность, что таким образом данные вы соберёте не все.
              0
              Тут не совсем с Вами соглашусь. Понятно, что многое зависит от самого оборудования, не так давно разбирался с техподдержкой одного вендора как раз по поводу фризов при опросе LLDP таблиц. Из-за того, что один из индексов они отдавали в HEX вместо STRING обработка увеличивалась на 2-6 секунд. Но…
              На том же Perl я сравнивал две реализации работы с snmp, тот же SNMP.pm и Net::SNMP. Первая однозначно выигрывала по скорости. Потом многое зависит того используются ли запросы типа snmptable или getnext, при правильно сформированном запросе можно получить заметный прирост в производительности. Как ни странно, многое зависит от того, пользуетесь ли вы текстовыми идентификаторами или цифровыми OID, вернее как реализовано преобразование. Если NMS перегружена MIB, а как правило в дефолтных инсталляциях так и есть, скорость так же падает.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое