
Estoy trabajando en un servidor que usa Vert.x en Java y noto algunos problemas de rendimiento cuando lo ejecuto en un servidor dedicado que ejecuta Ubuntu 12.04.
El servidor recoge las solicitudes HTTP entrantes, realiza cierta autenticación mediante HMAC, analiza los cuerpos de las solicitudes, realiza algún procesamiento de texto y envía datos a un servidor diferente a través de UDP. No hay E/S de disco y solo una cantidad relativamente pequeña de uso de memoria (ni cerca de intercambiar). Estoy realizando pruebas de carga en el servidor utilizando instancias de Grinder y AWS, pero incluso con un servidor bien equipado no puedo recibir más de 10.000 solicitudes por segundo.
Lo que estoy viendo es que un núcleo en la máquina del servidor está absolutamente anclado, principalmente en el kernel, y los otros núcleos tienen solo una utilización de ~20-25%. Mi suposición es que la CPU se gasta en recibir conexiones TCP entrantes. JMX informa la mayor parte de mi tiempo en io.netty.channel.nio.NioEventLoop.select(), lo que supongo cuenta el tiempo de espera por el kernel, y strace muestra una gran cantidad de tiempo invertido en futex() y epoll_wait(). Intenté jugar con la configuración del kernel para aumentar el rendimiento del servidor, pero no tuve suerte.
Ejecución del perfilador:
URL original:https://i.stack.imgur.com/6wIZA.png
Uso de CPU:
URL original:https://i.stack.imgur.com/9mM5u.png
Me pregunto qué se puede ajustar a nivel del kernel para ayudar con esto. Intenté alterar el tamaño del búfer TCP, aumentar los identificadores de archivos, desactivar las funciones TCP, etc., sin éxito. Este sistema operativo de servidor en realidad se ejecuta en Xen, está "dedicado" porque es el único residente.
Respuesta1
Examinaría su aplicación y las bibliotecas que utiliza. En lo que respecta al kernel de Linux, los subprocesos JVM se implementan como subprocesos nativos en Linux (procesos livianos), al menos con la implementación JVM de Sun/Oracle.
La JVM es un proceso único con muchos subprocesos. Cada hilo que genera puede ejecutarse en cualquiera de los núcleos disponibles. Un solo proceso en Linux puede tener muchos subprocesos.
También es posible que desees echar un vistazo a estos recursos: