Я разрабатываю часть корпоративного приложения на основе JBoss+EJB. Моему модулю необходимо обрабатывать огромное количество входящих UDP-пакетов. Я провел нагрузочное тестирование, и оказалось, что при отправке пакетов с интервалом 11 мс все нормально, но при интервале 10 мс некоторые пакеты теряются. На мой взгляд, это довольно странно, но я несколько раз сравнивал нагрузочные тесты с интервалом 10/11 мс, и результат всегда один и тот же (10 мс - какие-то "потерянные" пакеты, 11 мс - все нормально).
Если что-то было не так с синхронизацией, я ожидаю, что это также будет видно в случае 11-мс тестов (по крайней мере, один потерянный пакет или хотя бы одно неправильное значение счетчика). Так что, если это не из-за синхронизации, то, возможно, DatagramSocket, через который я получаю пакеты, не работает должным образом.
Я обнаружил, что размер приемного буфера (SO_RCVBUF) имеет значение по умолчанию 57344 (вероятно, это зависит от базовых сетевых буферов ввода-вывода). Я подозреваю, что, возможно, когда этот буфер заполняется, новые входящие дейтаграммы UDP отклоняются. Я попытался установить это значение немного выше, но заметил, что если я преувеличиваю, буфер возвращается к размеру по умолчанию. Если это зависит от базового уровня, как я могу узнать максимальный размер буфера для определенной ОС/сетевой карты на уровне JBoss?
Возможно ли, что это вызвано размером приемного буфера, или, может быть, значение 57344 достаточно велико для обработки большинства случаев? Есть ли у вас опыт решения таких вопросов?
В моем DatagramSocket не установлен тайм-аут. Мои дейтаграммы UDP содержат около 70 байт данных (значение без заголовка дейтаграммы).
[Отредактировано] Мне приходится использовать UDP, потому что я получаю данные Cisco Netflow — это протокол, используемый сетевыми устройствами для отправки некоторой статистики трафика. Кроме того, я не имею никакого влияния на формат отправляемых байтов (например, я не могу добавлять счетчики для пакетов и т. д.). Не ожидается, что все пакеты будут обработаны (некоторые дейтаграммы могут быть потеряны), но я ожидаю, что обработаю большую часть пакетов. Во время тестов с интервалом 10 мс было потеряно около 30% пакетов.
Маловероятно, что медленная обработка вызывает эту проблему. В настоящее время компонент singleton содержит ссылку на DatagramSocket, вызывающий метод получения в цикле. Когда пакет получен, он передается в очередь и обрабатывается выбранным из пула компонентом без сохранения состояния. «Фасадный» синглтон отвечает только за получение пакетов и передачу их на обработку (он не ждет завершения обработки).
Заранее спасибо, Петр