Java I/O против Java новый I/O (NIO) с Linux NPTL

Мои веб-серверы используют обычный ввод-вывод Java с механизмом потока на соединение. В настоящее время они становятся на колени с увеличенным пользователем (длинное соединение опроса). Тем не менее, соединения в основном простаивают. Хотя это можно решить путем добавления большего количества веб-серверов, я пытался провести некоторые исследования по реализации NIO.

У меня сложилось смешанное впечатление об этом. Я читал о тестах, где обычный ввод-вывод с новой библиотекой NPTL в Linux превосходит NIO.

Каков реальный опыт настройки и использования новейшего NPTL для Linux с Java I/O? Есть ли повышенная производительность?

И в более широком смысле вопрос:

Какое максимальное количество операций ввода-вывода и блокирования потоков (которые мы настраиваем в пуле потоков Tomcat) на стандартном компьютере серверного класса (Dell с четырехъядерным процессором) мы ожидаем нормального выполнения (с библиотекой Linux NPTL?). Каково влияние, если пул потоков становится действительно большим, скажем, более 1000 потоков?

Любые ссылки и указатели будут очень благодарны.

3 ответа

Решение

Провокационные сообщения в блоге: "Избегайте NIO, получите лучшую пропускную способность". Блог Пола Тима (2008) утверждает, что около 5000 потоков без каких-либо проблем; Я слышал, что люди утверждают больше:

  1. При включенном NPTL Sun и Blackwidow JVM 1.4.2 легко масштабируются до 5000+ потоков. Модель блокировки была последовательно на 25-35% быстрее, чем при использовании селекторов NIO. Было использовано множество методов, предложенных людьми из EmberIO - использование нескольких селекторов, многократное чтение (2), если первое чтение вернуло эквивалент EAGAIN в Java. Тем не менее, мы не могли превзойти простой поток для каждой модели соединения с Linux NPTL.

Я думаю, что ключевым моментом здесь является измерение накладных расходов и производительности и переход к неблокирующему вводу / выводу только тогда, когда вы знаете, что это необходимо, и можете продемонстрировать улучшение. Дополнительные усилия по написанию и поддержке неблокирующего кода должны быть учтены в вашем решении. Я считаю, что если ваше приложение может быть четко выражено с помощью синхронного / блокирующего ввода-вывода, сделайте это. Если ваше приложение поддается неблокирующему вводу / выводу, и вы не будете просто заново изобретать блокирующий ввод / вывод в пространстве приложения, РАССМОТРИТЕ переходить на nio, основываясь на потребностях измеренной производительности. Я удивляюсь, когда осматриваю результаты поиска в Google по этому поводу, как мало ресурсов приводят какие-либо (последние) цифры!

Также см. Слайды презентации Пола Тима: Старый путь снова новый. Основываясь на его работе в Google, конкретные цифры говорят о том, что синхронный многопоточный ввод / вывод является достаточно масштабируемым в Linux, и считают, что "NIO быстрее" - миф, который был верным некоторое время, но уже не так. Несколько хороших дополнительных комментариев здесь на Comet Daily. Он цитирует следующий (анекдотический, все еще нет твердой ссылки на тесты и т. Д.) Результат по NPTL:

В тестах NPTL удалось запустить 100 000 потоков на IA-32 за две секунды. Для сравнения, этот тест под ядром без NPTL занял бы около 15 минут.

Если вы действительно столкнулись с проблемами масштабируемости, вы можете настроить размер стека с помощью XX:ThreadStackSize, Поскольку вы упоминаете Tomcat, смотрите здесь.

Наконец, если вы связаны и решили использовать неблокирующий ввод / вывод, приложите все усилия для того, чтобы основываться на существующей среде людьми, которые знают, что они делают. Я потратил слишком много своего собственного времени, пытаясь найти правильное сложное неблокирующее решение ввода / вывода (по неправильным причинам).

Смотри также связанные по SO.

Ссылки, которые вы можете найти полезными:

Вы также можете взглянуть на http://nodejs.org/ который не является технологией JVM, но отлично обрабатывает тысячи соединений (и, если я не ошибаюсь, использует NPTL за кулисами)

Несколько хорошо зарекомендовавших себя веб-платформ NIO под JVM:

Саджид, я вижу, что вы делаете комету (длинный опрос).

Почти никто не говорит о проблеме выполнения пользовательского кода для событий Comet в NIO. Поток NIO, отправляющий события Comet, вызывает ваш код, если ваш код недостаточно хорош, вы блокируете этот критический поток, и другие соединения Comet ДОЛЖНЫ ЖДАТЬ, потому что поток NIO выполняет ту же работу, что и планировщик потока SO. Это не проблема в Comet с IO, потому что поток предназначен только для вашего события / задачи Comet, и планировщик может отказаться от вашего потока, когда захочет (не так просто с подходом NIO).

Единственная проблема, которую я вижу с "синхронной кометой" (основанной на IO), это потребление памяти стеками потоков.

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

Другие вопросы по тегам