Проблема производительности сокета Java TCP / IP - PullRequest
10 голосов
/ 14 марта 2011

Наше приложение очень быстро читает данные через сокеты TCP / IP в Java.Мы используем библиотеку NIO с неблокирующими сокетами и селектором для указания готовности к чтению.В среднем общее время обработки для чтения и обработки прочитанных данных составляет менее миллисекунды.Однако мы часто видим всплески в 10-20 миллисекунд.(работает в Linux).

Используя tcpdump , мы можем увидеть разницу во времени между чтением 2 дискретных сообщений tcpdump и сравнить это со временем наших приложений.Мы видим, что tcpdump , похоже, не имеет задержки, тогда как приложение может показывать 20 миллисекунд.

Мы почти уверены, что это не GC, поскольку журнал GC практически не показывает Full GC иJDK 6 (из того, что я понимаю) GC по умолчанию является параллельным, поэтому он не должен приостанавливать потоки приложения (если не выполняется Full GC).

Похоже, что для метода Selector.select(0) Java существует некоторая задержка для возврата готовности к чтению, поскольку на уровне TCP данные уже доступны для чтения (и tcpdump читает это).

Дополнительная информация: при пиковой нагрузке мы обрабатываем около 6000 x 150 байт в среднем на сообщение или около 900 МБ в секунду.

Ответы [ 4 ]

4 голосов
/ 15 марта 2011

eden collection по-прежнему подвергается паузе STW, поэтому 20 мс могут быть совершенно нормальными в зависимости от поведения распределения и размера кучи / размера живого набора.

3 голосов
/ 14 марта 2011

Ваш Java-код работает под RTLinux или каким-либо другим дистрибутивом с возможностью жесткого планирования в реальном времени? Если нет, то джиттер в 10-20 мс во время обработки кажется вполне разумным и ожидаемым.

2 голосов
/ 22 июня 2011

У меня была та же проблема в Java-сервисе, над которым я работаю.При повторной отправке одного и того же запроса от клиента сервер блокируется в одном и том же месте потока в течение 25-35 мс.Отключение алгоритма Нейгла в сокете исправило это для меня.Это может быть достигнуто путем вызова setTcpNoDelay (true) на сокете.Это может привести к увеличению перегрузки сети, поскольку ACK теперь будут отправляться как отдельные пакеты.См. http://en.wikipedia.org/wiki/Nagle%27s_algorithm для получения дополнительной информации об алгоритме Нейгла.

1 голос
/ 14 марта 2011

Из tcpdump faq :

КОГДА ИЗМЕРЕНО ВРЕМЯ ПАКЕТА? КАК ТОЧНО ЛИ ВРЕМЯ?

В большинстве операционных систем, на которых установлены tcpdump и запустить libpcap, пакет - время штамп как часть процесса драйвер устройства сетевого интерфейса или сетевой стек, обрабатывающий его. Это означает, что пакет не время штамп в тот момент, когда он прибывает на сетевом интерфейсе; после пакет приходит в сеть интерфейс, будет задержка до прерывание доставлено или опрашивается сетевой интерфейс (т.е. сетевой интерфейс может не прерываться Хост сразу - водитель может быть настроен на опрос интерфейса, если сетевой трафик тяжел, чтобы уменьшить количество прерываний и процесс больше пакетов на прерывание), и там будет дальнейшая задержка между точка, в которой начинается прерывание обрабатывается и отметка времени генерируется.

Таким образом, вероятность того, что временная метка создается на привилегированном уровне ядра, а потерянные 20 мс - это издержки на переключение контекста обратно в пространство пользователя и в Java и логику селектора сети JVM. Без дополнительного анализа системы в целом я не думаю, что можно сделать утвердительный выбор причины.

...