GETBULK SNMP4J Запрос

Я использую snmp4j, чтобы попытаться выполнить функции SNMP для удаленного агента. Из-за ряда ограничений, на которые мы не можем повлиять, мне нужно выполнить GETBULK, чтобы получить большую таблицу за короткий промежуток времени.

Моя текущая реализация:

public Map<String, String> doGetBulk(@NotNull VariableBinding... vbs)  
        throws IOException {

        Map<String, String> result = new HashMap<>();
        Snmp snmp = null;

        try {

            // Create TransportMapping and Listen
            TransportMapping transport = new DefaultUdpTransportMapping();
            snmp = new Snmp(transport);
            transport.listen();

            PDU pdu = new PDU();
            pdu.setType(PDU.GETBULK);
            pdu.setMaxRepetitions(200);
            pdu.setNonRepeaters(0);
            pdu.addAll(vbs);

            ResponseEvent responseEvent = snmp.send(pdu, this.target);
            PDU response = responseEvent.getResponse();

            // Process Agent Response
            if (response != null) {
                for(VariableBinding vb : response.getVariableBindings()) {
                    result.put("." + vb.getOid().toString(), vb.getVariable().toString());
                }
            } else {
                LOG.error("Error: Agent Timeout... ");
            }

        } catch (NullPointerException ignore) {
            // The variable table is null
        } finally {
            if (snmp != null) snmp.close();
        }
        return result;
    }

Однако это всегда возвращает 100 результатов, когда я знаю, что их 5000+. Я знаю, что не могу превысить размер PDU, поэтому у меня проблема с усечением ответа на блоки по 100, но я не могу понять, как я могу получить дескриптор каскадного запроса для получения следующих 100 записей.


person tarka    schedule 23.05.2017    source источник


Ответы (3)


Не рекомендуется использовать MaxRepetitions > 100 из-за фрагментации пакетов TCP/IP и природы UDP, которая не гарантирует порядок пакетов. Таким образом, большинство сред и агентов SNMP имеют такое встроенное ограничение.

person Andrew Komiagin    schedule 25.05.2017

Все детали уже есть в документе RFC,

https://tools.ietf.org/html/rfc1905

4.2.3 рассказывает, как сторона агента должна обрабатывать запросы GET BULK, и

Хотя максимальное количество привязок переменных в Response-PDU
ограничено N + (M * R), ответ может быть сгенерирован с меньшим
количеством привязок переменных (возможно, нулевым) для любой из трех< бр> причины.

(1) Если размер сообщения, инкапсулирующего Response-PDU, содержащего запрошенное количество привязок переменных, будет больше либо локального ограничения, либо максимального размера сообщения отправителя, то ответ генерируется с меньшим количеством привязок переменных. . Это меньшее число является упорядоченным набором привязок переменных с некоторыми удаленными привязками переменных в конце набора, так что размер сообщения, инкапсулирующего Response-PDU, приблизительно равен, но не больше либо локального ограничения, либо максимальный размер сообщения отправителя. Обратите внимание, что количество удаленных привязок переменных не имеет отношения к значениям N, M или R.

(2) Ответ также может быть сгенерирован с меньшим количеством привязок переменных, если для некоторого значения итерации i, такого, что i больше нуля и меньше или равно M, все сгенерированные привязки переменных имеют поле значения установите в `endOfMibView'. В этом случае привязки переменных могут быть усечены после (N + (i * R))-й привязки переменных.

(3) В случае, если обработка запроса с большим количеством повторений требует значительно большего времени обработки, чем обычный запрос, то агент может завершить запрос с числом повторений, меньшим полного, при условии, что выполнено хотя бы одно повторение. завершенный.

О том, как выполнить серию правильных операций GET BULK для запроса всех данных, которые вы хотите, вы можете обратиться к разделу 4.2.3.1 в качестве примера.

person Lex Li    schedule 29.05.2017

Вы установили максимальное количество повторений на 200, то есть сервер может отправить вам не более 200 строк. Итак, с одной стороны, вы никогда не получите более 200 строк (и меньше всего 5000 и более). С другой стороны, сервер может решить отправить вам меньше строк, это практически выбор сервера; вы говорите ему, что вы в состоянии обработать.

Обычно вы запрашиваете 10-50 строк максимум. (Кстати: есть много серверов с ошибочными реализациями SNMP, и чем выше вы установите максимальное количество повторений, тем выше шанс, что вы вообще ничего не получите.)

Таким образом, вы должны запрашивать набор строк за набором строк. Поскольку вы, вероятно, не хотите реализовывать это самостоятельно, я бы рекомендовал использовать TableUtils класс. Просто начните с getTable().

person steffen    schedule 29.05.2017