Como sugiere el título de la pregunta, estoy teniendo dificultades para descubrir qué se puede mejorar en mi aplicación (o sintonizado en el sistema operativo, ubuntu) para lograr un rendimiento aceptable. Pero primero explicaré la arquitectura:
El servidor front-end es una máquina de 8 núcleos con 8 gigas de RAM que ejecuta Ubuntu 12.04. La aplicación está escrita completamente en javascript y se ejecuta en node.js v 0.8.22 (ya que algunos módulos parecen quejarse en las versiones más recientes del nodo). Uso nginx 1.4 para proxy del tráfico http desde el puerto 80 y 443 a 8 trabajadores de nodo que se gestionan y comenzó a usar la API de clúster de nodo Utilizo la última versión de socket.io 0.9.14 para manejar las conexiones websocket, en las que he habilitado solo websockets y xhr-polling como transportes disponibles. En esta máquina también ejecuto una instancia de Redis (2.2)
Almaceno datos persistentes (como usuarios y puntajes) en un segundo servidor en mongodb (3.6) con 4 gigs de RAM y 2 núcleos.
La aplicación está en producción desde hace unos meses (se ha estado ejecutando en una sola caja hasta hace unas semanas) y está siendo utilizada por alrededor de 18k usuarios por día. Siempre ha funcionado muy bien aparte de un problema principal: la degradación del rendimiento. Con el uso, la cantidad de CPU utilizada por cada proceso aumenta hasta que estatiza al trabajador (que ya no atenderá solicitudes). Lo he resuelto temporalmente comprobando la CPU en uso por cada trabajador cada minuto y reiniciando si alcanza el 98%. Entonces, el problema aquí es principalmente CPU, y no RAM. La RAM ya no es un problema ya que he actualizado a socket.io 0.9.14 (la versión anterior tenía pérdidas de memoria), así que dudo que sea un problema de pérdida de memoria, especialmente porque ahora es la CPU que crece bastante rápido ( ¡Tengo que reiniciar a cada trabajador alrededor de 10-12 veces al día!). La RAM en uso también crece para ser honesto, pero muy lentamente, 1 concierto cada 2-3 días de uso, y lo extraño es que no se libera incluso cuando reinicio por completo toda la aplicación. ¡Solo se lanza si reinicio el servidor! esto realmente no puedo entender ...
Ahora descubrí nodefly, que es increíble, así que finalmente puedo ver lo que está sucediendo en mi servidor de producción, y estoy recopilando datos desde hace un par de días. Si alguien quiere ver los cuadros, puedo darle acceso, ¡pero básicamente puedo ver que tengo entre 80 y 200 conexiones simultáneas! Esperaba que node.js manejara miles, no cientos de solicitudes. Además, el tiempo de respuesta promedio para el tráfico http flota entre 500 y 1500 milisegundos, lo que creo que es realmente mucho. Además, en este mismo momento con 1300 usuarios en línea, esta es la salida de "ss -s":
Total: 5013 (kernel 5533)
TCP: 8047 (estab 4788, closed 3097, orphaned 139, synrecv 0, timewait 3097/0), ports 0
Transport Total IP IPv6
* 5533 - -
RAW 0 0 0
UDP 0 0 0
TCP 4950 4948 2
INET 4950 4948 2
FRAG 0 0 0
lo que muestra que tengo muchas conexiones cerradas en el tiempo de espera. He aumentado los archivos abiertos máximos a 999999, aquí está la salida de ulimit -a:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 63724
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 999999
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 63724
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Así que pensé que el problema podría estar en el tráfico http que, por alguna razón, satura los puertos / sockets disponibles (?), Pero una cosa no tiene sentido para mí: por qué cuando reinicio a los trabajadores y todos los clientes se vuelven a conectar en unos segundos, la carga en la CPU del trabajador baja al 1% y es capaz de atender las solicitudes correctamente hasta que se satura después de aproximadamente 1 hora (en la hora pico)?
Soy principalmente un programador de JavaScript, no un administrador del sistema, por lo que no sé cuánta carga debería esperar manejar con mis servidores, pero seguramente no está funcionando como debería. De lo contrario, la aplicación es estable y este último problema me impide enviar las versiones móviles de la aplicación que están listas, ya que obviamente traerán más carga y eventualmente colapsarán todo.
Espero que haya algo obvio que estoy haciendo mal, y alguien ayudará a detectarlo ... no dude en pedirme más información, y lo siento por la longitud de la pregunta, pero fue necesario, creo ... ¡gracias por adelantado!
top
cuando el uso de la CPU está cerca del 100%?