Recientemente he estado aprendiendo sobre el monitoreo de Nodejs. Aunque no tengo la energía para aprender a escribir una versión simple de monitoreo, todavía no puedo evitar aprender cómo obtener estos indicadores (después de consultar mucha información, siento). (También estoy resolviendo los puntos de conocimiento del nodo del servidor, así que los resumiré en este artículo y los compartiré con usted).
Puede que haya problemas con algunos de los indicadores de este artículo. De hecho, puede organizar estos datos y escribirlos en una biblioteca de seguimiento y utilizarlos en sus propios proyectos pequeños y medianos. Luego, el front-end reacciona con herramientas como bizcharts y g2, y el front-end dibuja la pantalla grande de datos por sí mismo. Creo que las dimensiones de los datos recopilados por esay monitor no son tan completas como las nuestras.
Los cuellos de botella en el rendimiento de los servidores suelen ser los siguientes:
de uso de CPU y carga de CPU, los cuales pueden reflejar el nivel de actividad de una máquina hasta cierto punto.
El uso de CPU son los recursos de CPU ocupados por los programas en ejecución, lo que indica cómo la máquina ejecuta los programas en un momento determinado. Cuanto mayor sea la tasa de uso, significa que la máquina está ejecutando muchos programas en este momento y viceversa. El nivel de uso está directamente relacionado con la potencia de la CPU. Primero comprendamos las API relevantes y algunas explicaciones terminológicas que nos ayudarán a comprender el código para obtener el uso de la CPU.
os.cpus()
devuelve una matriz de objetos que contienen información sobre cada núcleo lógico de la CPU.
modelo: una cadena que especifica el modelo del núcleo de la CPU.
velocidad: número que especifica la velocidad del núcleo de la CPU en MHz.
veces: Un objeto que contiene las siguientes propiedades:
NOTA: El nice
valor es solo para POSIX. En los sistemas operativos Windows, el valor de nice
siempre es 0 para todos los procesadores.
Cuando ve el usuario y los campos agradables, algunos estudiantes están confundidos acerca de las ventajas, y yo también, así que pregunté cuidadosamente sobre su significado, continúe.
usuario indica la proporción de tiempo que la CPU está funcionando en modo de usuario .
La ejecución del proceso de aplicación se divide en modo usuario y modo kernel : la CPU ejecuta la propia lógica del código del proceso de la aplicación en modo usuario, generalmente algunos cálculos lógicos o numéricos. La CPU ejecuta llamadas al sistema iniciadas por el proceso en modo kernel, generalmente en respuesta; a la solicitud de recursos del proceso.
Un programa de espacio de usuario es cualquier proceso que no forma parte del núcleo. Shells, compiladores, bases de datos, servidores web y programas relacionados con el escritorio son todos procesos del espacio de usuario. Si el procesador no está inactivo, es normal que la mayor parte del tiempo de la CPU se dedique a ejecutar procesos en el espacio del usuario.
Nice representa la proporción de tiempo que la CPU se ejecuta en modo de usuario de baja prioridad . La prioridad baja significa que el valor de nice del proceso es menor que 0.
El usuariorepresenta la proporción de tiempo que la CPU se ejecuta en modo kernel .
En términos generales, el uso de CPU en modo kernel no debería ser demasiado alto a menos que el proceso de la aplicación inicie una gran cantidad de llamadas al sistema. Si es demasiado alto, significa que la llamada al sistema lleva mucho tiempo, como operaciones IO frecuentes.
inactivoindica la proporción de tiempo que la CPU está en estado inactivo, en el que la CPU no tiene tareas que realizar.
irq representa la proporción de tiempo que la CPU maneja las interrupciones de hardware .
La interrupción de la tarjeta de red es un ejemplo típico: después de que la tarjeta de red recibe el paquete de datos, notifica a la CPU para su procesamiento mediante una interrupción de hardware. Si el tráfico de la red del sistema es muy intenso, se puede observar un aumento significativo en el uso de irq.
si el estado del usuario es inferior al 70%, el estado del núcleo es inferior al 35% y el estado general es inferior al 70%, se puede contar como un estado saludable.
El siguiente ejemplo ilustra el uso del método os.cpus() en Node.js:
Ejemplo 1:
// Programa Node.js para demostrar la //método os.cpus() // Asignación del módulo del sistema operativo sistema operativo constante = requerir ('sistema operativo'); //Imprimiendo valores de os.cpus() console.log(os.cpus());
Salida:
[ {modelo:'CPU Intel(R) Core(TM) i5-7200U a 2,50 GHz', velocidad: 2712, veces: { usuario:900000, nice:0, sys:940265, inactivo:11928546, irq:147046 } }, {modelo:'CPU Intel(R) Core(TM) i5-7200U a 2,50 GHz', velocidad: 2712, veces: { usuario:860875, nice:0, sys:507093, inactivo:12400500, irq:27062 } }, {modelo:'CPU Intel(R) Core(TM) i5-7200U a 2,50 GHz', velocidad: 2712, veces: { usuario:1273421, nice:0, sys:618765, inactivo:11876281, irq:13125 } }, {modelo:'CPU Intel(R) Core(TM) i5-7200U a 2,50 GHz', velocidad: 2712, veces: { usuario:943921, nice:0, sys:460109, idle:12364453, irq:12437 } } ]
El siguiente es el código sobre cómo obtener la utilización de la CPU
const os = require('os'); const dormir = ms => nueva Promesa(resolver => setTimeout(resolver, ms)); clase OSUtils { constructor() { this.cpuUsageMSDefault = 1000; //período predeterminado de utilización de la CPU} /** * Obtener la utilización de la CPU durante un período de tiempo determinado* @param {Número} Opciones.ms [Período de tiempo, el valor predeterminado es 1000 ms, que es 1 segundo] * @param { Boolean } Options.percentage [verdadero (devuelto como resultado porcentual) falso] | * @returns { Promesa } */ async getCPUUsage(opciones={}) { constante eso = esto; let { cpuUsageMS, porcentaje } = opciones; cpuUsageMS = cpuUsageMS || eso.cpuUsageMSDefault; const t1 = that._getCPUInfo(); // información de la CPU en el punto de tiempo t1 en espera de suspensión (cpuUsageMS); const t2 = that._getCPUInfo(); // información de la CPU en el punto de tiempo t2 const idle = t2.idle - t1.idle; total constante = t2.total - t1.total; let use = 1 - inactivo / total; if (porcentaje) de uso = (uso * 100.0).toFixed(2) + "%"; uso de devolución; } /** * Obtener información de tiempo instantáneo de la CPU * @returns { Objeto } Información de la CPU * usuario <número> La cantidad de milisegundos que la CPU pasó en modo de usuario. * nice <número> El número de milisegundos que la CPU pasa en modo agradable. * sys <número> Número de milisegundos que la CPU pasó en modo sistema. * inactivo <número> El número de milisegundos que la CPU pasó en modo inactivo. * irq <número> El número de milisegundos que la CPU pasó en modo de solicitud de interrupción. */ _getCPUInfo() { const cpus = sistema operativo.cpus(); let usuario = 0, nice = 0, sys = 0, inactivo = 0, irq = 0, total = 0; para (dejar cpu en cpus) { tiempos constantes = cpus[cpu].times; usuario += veces.usuario; agradable += veces.bonito; sys += veces.sys; inactivo += veces.inactivo; irq += veces.irq; } total += usuario + agradable + sys + inactivo + irq; devolver { usuario, sistema, inactivo, total, } } } const cpuUsage = new OSUtils().getCPUUsage({ porcentaje: verdadero }); console.log('cpuUsage: ', cpuUsage.then(data=>console.log(data))); // Mi computadora tiene
. La carga de la CPU (loadavg) es fácil de entender y se refiere a un determinado. período de tiempo El número de procesos que ocupan tiempo de CPU y procesos que esperan tiempo de CPU es el promedio de carga. Los procesos que esperan tiempo de CPU aquí se refieren a procesos que esperan ser despertados, excluyendo los procesos en estado de espera.
Antes de esto, necesitamos aprender una API de nodo
os.loadavg()
que devuelve una matriz que contiene una carga promedio de 1, 5 y 15 minutos.
El promedio de carga es una medida de la actividad del sistema calculada por el sistema operativo y expresada como decimal.
El promedio de carga es un concepto específico de Unix. En Windows, el valor de retorno siempre es [0, 0, 0]
Se utiliza para describir la ocupación actual del sistema operativo. Puede entenderse simplemente como el número promedio de tareas que la CPU está usando y esperando para usar. CPU por unidad de tiempo. La carga de la CPU es demasiado alta, lo que indica que hay demasiados procesos en Node, lo que puede reflejarse en el inicio repetido de nuevos procesos utilizando el módulo Ciudad Prohibida.
sistema operativo constante = requerir ('sistema operativo'); //Número de subprocesos de CPU longitud constante = os.cpus().length; // La carga promedio de una CPU de un solo núcleo devuelve una matriz que contiene la carga promedio de 1, 5 y 15 minutos os.loadavg().map(load => load / length
Primero expliquemos una API
);, de lo contrario no podrá leerlo. Comprenda nuestro código para obtener indicadores de memoria,
esta función devuelve 4 parámetros, los significados y diferencias son los siguientes:
Utilice el siguiente código para imprimir el uso de memoria de un proceso secundario. Se puede ver que rss es aproximadamente igual al RES del comando superior. Además, la memoria del proceso principal es de solo 33 M, que es más pequeña que la memoria del proceso secundario. Se puede ver que su uso de memoria se calcula de forma independiente.
var mostrarMem = función(){ var mem = proceso.memoryUsage(); formato var = función (bytes) { retorno (bytes/1024/1024).toFixed(2) + 'MB'; }; console.log('Proceso: heapTotal ' + formato(mem.heapTotal) + 'heapUsed ' + formato(mem.heapUsed) + 'rss ' + formato(mem.rss) + 'externo:' + formato(mem.external) ); console.log('----------------------------------------------------- --- ---------------'); };
Para Node, una vez que ocurre una pérdida de memoria, no es tan fácil solucionar el problema. Si se monitorea que la memoria solo aumenta pero no disminuye, entonces debe haber un problema de pérdida de memoria. El uso saludable de la memoria debería aumentar y disminuir. Cuando el acceso es grande, aumenta y cuando el acceso cae, disminuye.
const os = require('os'); // Verifique el uso de memoria del proceso actual del Nodo const { rss, heapUsed, heapTotal } = process.memoryUsage(); // Obtener memoria libre del sistema const systemFree = os.freemem(); // Obtener la memoria total del sistema const systemTotal = os.totalmem(); módulo.exportaciones = { memoria: () => { devolver { sistema: 1 - systemFree / systemTotal, // montón de uso de memoria del sistema: heapUsed / headTotal, // uso de memoria del proceso del nodo actual nodo: rss / systemTotal, // relación de uso de memoria del proceso del nodo actual de la memoria del sistema} } }
La supervisión del disco supervisa principalmente el uso del disco. Debido a la escritura frecuente de registros, el espacio en disco se agota gradualmente. Una vez que el disco no sea suficiente, causará varios problemas en el sistema. Establezca un límite superior para el uso del disco Una vez que el uso del disco exceda el valor de advertencia, el administrador del servidor debe organizar los registros o limpiar el disco.
El siguiente código se refiere a easy monitor 3.0.
const { execSync } = require('child_process'); resultado constante = execSync('df -P', {codificación: 'utf8'}) líneas constantes = resultado.split('n'); métrica constante = {}; lineas.forEach(linea => { si (line.startsWith('/')) { coincidencia constante = line.match(/(d+)%s+(/.*$)/); si (coincidencia) { tasa constante = parseInt(match[1] || 0); constante montado = coincidencia[2]; if (!mounted.startsWith('/Volumes/') && !mounted.startsWith('/privado/')) { métrica[montada] = tasa; } } } }); console.log(metric)
La carga de E/S se refiere principalmente a E/S de disco. Refleja la situación de lectura y escritura en el disco. Para las aplicaciones escritas por Node, que son principalmente para servicios de red, es poco probable que la carga de E/S sea demasiado alta. La presión de E/S de muchas lecturas proviene de la base de datos. .
Para obtener indicadores de E/S, debemos comprender un comando de Linux llamado iostat. Si no está instalado, debemos instalarlo. Veamos por qué este comando puede reflejar los indicadores de E/S
iostat -dx.
Descripción de la propiedad
rrqm/s: número de operaciones de lectura de combinación por segundo. Es decir, rmerge/s (la cantidad de veces que las solicitudes de lectura al dispositivo se fusionan por segundo, y el sistema de archivos fusionará las solicitudes para leer el mismo bloque) wrqm/s: el número de operaciones de escritura de combinación por segundo. Es decir, wmerge/s (el número de veces que se combinan las solicitudes de escritura en el dispositivo por segundo) r/s: el número de lecturas del dispositivo de E/S completadas por segundo. eso es rio/s w/s: el número de escrituras en el dispositivo de E/S completadas por segundo. Eso es wio/s rsec/s: Número de sectores leídos por segundo. Eso es rsecta/s wsec/s: Número de sectores escritos por segundo. es decir, wsect/s rkB/s: K bytes leídos por segundo. Es la mitad de rsect/s porque el tamaño de cada sector es de 512 bytes. wkB/s: Número de K bytes escritos por segundo. Es la mitad de wsect/s. avgrq-sz: tamaño de datos promedio (sectores) por operación de E/S del dispositivo. avgqu-sz: longitud promedio de la cola de E/S. await: el tiempo de espera promedio (milisegundos) para cada operación de E/S del dispositivo. svctm: tiempo de procesamiento promedio (milisegundos) de cada operación de E/S del dispositivo. %util: qué porcentaje de un segundo se utiliza para las operaciones de E/S, es decir, el porcentaje de CPU consumido por IO.
Solo necesitamos monitorear %util
si %util está cerca del 100% , significa que hay demasiados I. Se generan solicitudes de E/S. El sistema de E/S está completamente cargado y puede haber un cuello de botella en este disco.
Si await es mucho mayor que svctm, significa que la cola de E/S es demasiado larga y el tiempo de respuesta de la aplicación se vuelve más lento. Si el tiempo de respuesta excede el rango que el usuario puede tolerar, puede considerar reemplazar un disco más rápido. ajustar el algoritmo del elevador del núcleo y optimizar la aplicación, o actualizar la CPU.
monitorea el tiempo de respuesta de la página de Nodejs. La solución se selecciona del artículo del blog del profesor Liao Xuefeng.
Recientemente quiero monitorear el rendimiento de Nodejs. Grabar y analizar el registro es demasiado problemático. La forma más sencilla es registrar el tiempo de procesamiento de cada solicitud HTTP y devolverlo directamente en el encabezado de respuesta HTTP.
Registrar la hora de una solicitud HTTP es muy simple. Significa registrar una marca de tiempo al recibir la solicitud y registrar otra marca de tiempo al responder a la solicitud. La diferencia entre las dos marcas de tiempo es el tiempo de procesamiento.
Sin embargo, el código res.send() se distribuye en varios archivos js, por lo que no se pueden cambiar todas las funciones de procesamiento de URL.
La idea correcta es utilizar middleware para lograrlo. Pero Nodejs no tiene ningún método para interceptar res.send(), ¿cómo romperlo?
De hecho, siempre que cambiemos ligeramente nuestra forma de pensar, abandonemos el método tradicional de programación orientada a objetos y veamos res.send () como un objeto de función, primero podemos guardar la función de procesamiento original res.send y luego reemplazar res.send con nuestro Función de procesamiento propia:
app.use (función (req, res, next) { // Hora de inicio del registro: var exec_start_at = Fecha.ahora(); //Guardar la función de procesamiento original: var _send = res.enviar; // Vinculamos nuestra propia función de controlador: res.enviar = función () { //Enviar encabezado: res.set('X-Execution-Time', String(Date.now() - exec_start_at)); // Llama a la función de procesamiento original: return _send.apply(res, argumentos); }; próximo(); });
en solo unas pocas líneas de código, la marca de tiempo está lista.
No es necesario procesar el método res.render() porque res.render() llama internamente a res.send().
Al llamar a la función apply(), es importante pasar el objeto res; de lo contrario, esto de la función de procesamiento original apunta a indefinido, lo que conduce directamente a un error.
Tiempo de respuesta medido de la página de inicio 9 milisegundos
Glosario QPS:
QPS: Consultas por segundo significa "tasa de consultas por segundo", que es la cantidad de consultas a las que un servidor puede responder. por segundo, es una medida de cuánto tráfico maneja un servidor de consultas específico dentro de un período de tiempo específico.
En Internet, el rendimiento de una máquina que sirve como servidor del sistema de nombres de dominio a menudo se mide por la tasa de consultas por segundo.
TPS: es la abreviatura de TransactionsPerSecond, que es el número de transacciones/segundo. Es una unidad de medida para los resultados de las pruebas de software. Una transacción se refiere al proceso en el que un cliente envía una solicitud al servidor y el servidor responde. El cliente comienza a cronometrar cuando envía una solicitud y finaliza cuando recibe la respuesta del servidor para calcular el tiempo utilizado y el número de transacciones completadas.
QPS vs TPS: QPS es básicamente similar a TPS, pero la diferencia es que una visita a una página forma un TPS; pero una solicitud de página puede generar múltiples solicitudes al servidor, y el servidor puede contar estas solicitudes como "QPS". Por ejemplo, acceder a una página solicitará al servidor dos veces. Un acceso generará una "T" y dos "Q".
. Tiempo de respuesta: el tiempo total que lleva ejecutar una solicitud desde el principio hasta el final cuando se reciben los datos de respuesta, es decir, el tiempo desde que el cliente inicia la solicitud hasta que recibe el resultado de la respuesta del servidor.
El tiempo de respuesta RT (tiempo de respuesta) es uno de los indicadores más importantes de un sistema. Su valor numérico refleja directamente la velocidad del sistema.
El número de concurrencia se refiere a la cantidad de solicitudes que el sistema puede manejar al mismo tiempo. Esto también refleja la capacidad de carga del sistema.
El rendimiento (capacidad de soportar presión) del sistema está estrechamente relacionado con el consumo de CPU de solicitudes, interfaces externas, IO, etc. Cuanto mayor sea el consumo de CPU de una sola solicitud, más lenta será la interfaz del sistema externo y la velocidad de E/S, y menor será la capacidad de rendimiento del sistema, y viceversa.
Varios parámetros importantes del rendimiento del sistema: QPS (TPS), número de concurrencias y tiempo de respuesta.
QPS (TPS): (Consulta por segundo) Número de solicitudes/transacciones por segundo
Concurrencia: Número de solicitudes/transacciones procesadas por el sistema al mismo tiempo
Tiempo de respuesta: Generalmente, el tiempo de respuesta promedio
se calcula después de comprender el significado de lo anterior tres elementos.La relación entre ellos:
Entendamos los conceptos anteriores a través de un ejemplo. Según la regla 80/20, si el 80% de las visitas diarias se concentran en el 20% del tiempo, ese 20% del tiempo se denomina hora punta.
1, 300w por día PV en una sola máquina. ¿Cuántos QPS requiere esta máquina?
(3000000 * 0,8) / (86400 * 0,2) = 139 (QPS)
2. Si el QPS de una máquina es 58, ¿cuántas máquinas se necesitan para soportarlo?
139/58 = 3
En este punto, si realiza la arquitectura front-end de proyectos generales pequeños y medianos e implementa sus propios servicios de nodo, sabrá cuántas máquinas se necesitan para formar un clúster para informar ppt. Puedes calcular un valor aproximado con PV.
Necesitamos comprender la prueba de esfuerzo (necesitamos confiar en la prueba de esfuerzo para obtener qps. Tome el comando ab como ejemplo:
formato de comando:
ab [opciones] [http://]nombre de host[:puerto]/ruta
Común)
.Los parámetros son los siguientes:
-n solicitudes total Número de solicitudes -c concurrencia Número de concurrencia -t límite de tiempo El número máximo de segundos para la prueba, que puede considerarse como el tiempo de espera de la solicitud -p postfile Archivo que contiene datos que requieren POST -T tipo de contenido Información de encabezado de tipo de contenido utilizada por los datos POST Copiar código