
Я работаю на сервере, использующем Vert.x в Java, и замечаю некоторые проблемы с производительностью при работе на выделенном сервере под управлением Ubuntu 12.04.
Сервер принимает входящие HTTP-запросы, выполняет некоторую аутентификацию с использованием HMAC, анализирует тела запросов, выполняет некоторую обработку текста и отправляет данные на другой сервер по UDP. Дискового ввода-вывода нет, а объем используемой памяти относительно небольшой (даже близко не своп). Я провожу нагрузочное тестирование сервера с использованием экземпляров Grinder и AWS, но даже с хорошо оснащенным сервером я не могу получить больше 10 тыс. запросов в секунду.
Я вижу, что одно ядро на серверной машине полностью застряло, в основном в ядре, а другие ядра загружены всего на ~20-25%. Я предполагаю, что процессор тратится на прием входящих TCP-соединений. JMX сообщает большую часть моего времени в io.netty.channel.nio.NioEventLoop.select(), который, как я предполагаю, учитывает время ожидания ядра, а strace показывает много времени, проведенного в futex() и epoll_wait(). Я пробовал играть с настройками ядра, чтобы увеличить пропускную способность сервера, но мне это не удалось.
Прогон профилировщика:
Исходный URL-адрес:https://i.stack.imgur.com/6wIZA.png
Использование процессора:
Исходный URL-адрес:https://i.stack.imgur.com/9mM5u.png
Мне интересно, что можно настроить на уровне ядра, чтобы помочь с этим. Я пробовал возиться с размерами буфера TCP, увеличивать дескрипторы файлов, отключать функции TCP и т. д., но безрезультатно. Эта серверная ОС на самом деле работает на Xen, она «выделена», поскольку является единственным резидентом.
решение1
Я бы внимательно изучил ваше приложение и библиотеки, которые оно использует. Что касается ядра Linux, потоки JVM реализованы как собственные потоки в Linux (легковесные процессы), по крайней мере, с реализацией Sun/Oracle JVM.
JVM — это один процесс со множеством потоков. Каждый поток, который он раскручивает, может работать на любом из доступных ядер. Один процесс в Linux может иметь множество потоков.
Также вам, возможно, будет интересно взглянуть на эти ресурсы: