Один из наших серверов испытывает очень высокую нагрузку на процессор с нашим приложением. Мы рассмотрели различные характеристики и проблемы с поиском источника проблемы.Высокий CPU, возможно, из-за переключения контекста?
Одна из существующих теорий заключается в том, что задействовано слишком много потоков, и мы должны попытаться уменьшить количество одновременных выполнения потоков. Есть только один основной пул потоков, с 3000 потоками, и с ним работает WorkManager (это Java EE - Glassfish). В любой момент времени существует около 620 отдельных сетевых операций ввода-вывода, которые необходимо проводить параллельно (использование java.NIO также не является вариантом). Более того, существует около 100 операций, которые не связаны с IO и выполняются параллельно.
Эта структура неэффективна, и мы хотим увидеть, действительно ли она наносит ущерб, или это просто плохая практика. Причина в том, что любое изменение в этой системе довольно дорого (с точки зрения человеко-часов), поэтому нам нужно некоторое доказательство проблемы.
Итак, теперь мы задаемся вопросом, является ли контекстная переключение потоков причиной, поскольку существует гораздо больше потоков, чем требуемые параллельные операции. Посмотрев на журналы, мы видим, что в среднем за одну секунду выполняется 14 разных потоков. Если учесть наличие двух процессоров (см. Ниже), то это 7 потоков на процессор. Это не слишком много, но мы хотели проверить это.
Так что - мы можем исключить переключение контекста или слишком много нитей в качестве проблемы?
Общие детали:
- Java 1.5 (да, это старая), работает на CentOS 5, 64-бит, Linux ядра 2.6.18-128.el5
- Существует только один единственный процесс Java на машине, ничего больше.
- Два процессора под управлением VMware.
- 8GB ОЗУ
- У нас нет возможности запуска профилировщика на машине.
- У нас нет возможности обновить Java или ОС.
UPDATE Как сообщил ниже, мы провели захваты средней нагрузки (с использованием безотказной работы) и CPU (с помощью vmstat 1 120) на нашем тестовом сервере с различными нагрузками. Мы ждали 15 минут между каждым изменением нагрузки и ее измерениями, чтобы обеспечить, чтобы система стабилизировалась вокруг новой нагрузки и числа средних нагрузок обновляются:
50% загруженность производственного сервера: http://pastebin.com/GE2kGLkk
34 % загруженность производственного сервера: http://pastebin.com/V2PWq8CG
25% нагрузки производственного сервера: появляется http://pastebin.com/0pxxK0Fu
использования центрального процессора, чтобы быть уменьшено нагрузка уменьшает, но не на очень резкий уровень (изменения от 50% до 25 % на самом деле не составляет 50% сокращение использования ЦП). Средняя загрузка кажется несопоставимой с объемом рабочей нагрузки.
Существует также вопрос: если наш тестовый сервер также является виртуальной машиной, могут ли быть затронуты его измерения на процессорах других виртуальных машин, работающих на одном и том же хосте (что делает эти измерения бесполезными)?
ОБНОВЛЕНИЕ 2 Прикрепление снимок нитей из трех частей (Pastebin ограничений)
Часть 1: http://pastebin.com/DvNzkB5z
Часть 2: http://pastebin.com/72sC00rc
Часть 3: http://pastebin.com/YTG9hgF5
Ну, а как уменьшить количество потоков в пуле потоков и посмотреть, помогает ли это? – Voo
Высокое использование ЦП может быть хорошим: это означает, что использование ресурса ЦП является оптимальным. Ваши потоки что-то вычислили, не дожидаясь ввода-вывода или блокировки. Если у вас нет жесткой петли, потребляющей ваш процессор без необходимости, вы должны быть довольны высоким уровнем параллелизма, который вам удалось достичь. – dasblinkenlight
@dasblinkenlight Это правда, если нам удастся доказать, что нет ненужных отходов (например, переключение контекста).Если нам удастся это сделать, мы можем сказать системной команде добавить больше процессоров и оправдать то, что это такое. Но сначала мы должны сделать домашнее задание. – Yon