Node.js es la herramienta líder para crear aplicações de servidor en JavaScript, el lenguaje de programación más popular del mundo. Al ofrecer la funcionalidad tanto de un servidor web como de un servidor de aplicação , Node.js ahora se considera una herramienta clave para todo tipo de desarrollo y entrega basados en microservicios. (Descargue un informe gratuito de Forrester sobre Node.js y NGINX ).
Node.js puede reemplazar o ampliar Java o .NET para el desarrollo de aplicação backend.
Node.js es de un solo subproceso y utiliza E/S sin bloqueo, lo que le permite escalar y soportar decenas de miles de operaciones simultáneas. Comparte estas características arquitectónicas con NGINX y resuelve el problema C10K (soportar más de 10 000 conexiones simultáneas) que NGINX también fue inventado para resolver. Node.js es conocido por su alto rendimiento y productividad para los desarrolladores.
Entonces, ¿qué podría salir mal?
Node.js tiene algunos puntos débiles y vulnerabilidades que pueden hacer que los sistemas basados en Node.js sean propensos a un bajo rendimiento o incluso a fallas. Los problemas surgen con mayor frecuencia cuando una aplicação web basada en Node.js experimenta un rápido crecimiento del tráfico.
Además, Node.js es una excelente herramienta para crear y ejecutar la lógica de aplicação que produce el contenido central y variable para su página web. Pero no es tan bueno para servir contenido estático (imágenes y archivos JavaScript, por ejemplo) o para equilibrar la carga entre múltiples servidores.
Para aprovechar al máximo Node.js, debe almacenar en caché contenido estático, utilizar proxy y equilibrar la carga entre múltiples servidores de aplicação y administrar la contención de puertos entre clientes, Node.js y ayudantes, como servidores que ejecutan Socket.IO. NGINX se puede utilizar para todos estos propósitos, lo que lo convierte en una excelente herramienta para ajustar el rendimiento de Node.js.
Utilice estos consejos para mejorar el rendimiento de la aplicação Node.js:
Nota: Una solución rápida para mejorar el rendimiento de la aplicação Node.js es modificar su configuración de Node.js para aprovechar los servidores modernos de múltiples núcleos. Consulta la documentación de Node.js para aprender cómo hacer que Node.js genere procesos secundarios separados, iguales a la cantidad de CPU en tu servidor web. Luego, cada proceso encuentra, de manera casi mágica, un lugar en una y sólo una de las CPU, lo que le proporciona un gran aumento en el rendimiento.
En NGINX, Inc. siempre nos horrorizamos un poco cuando vemos servidores de aplicação expuestos directamente al tráfico entrante de Internet, utilizados en el núcleo de sitios de alto rendimiento. Esto incluye muchos sitios basados en WordPress , por ejemplo, así como sitios Node.js.
Node.js, en mayor medida que la mayoría de los servidores de aplicação , está diseñado para la escalabilidad, y su servidor web puede manejar mucho tráfico de Internet razonablemente bien. Pero el servicio web no es la razón de ser de Node.js; no es lo que realmente fue creado para hacer.
Si tiene un sitio con mucho tráfico, el primer paso para aumentar el rendimiento de la aplicação es colocar un servidor proxy inverso delante de su servidor Node.js. Esto protege al servidor Node.js de la exposición directa al tráfico de Internet y le permite una gran flexibilidad en el uso de múltiples servidores de aplicação , en el equilibrio de carga entre los servidores y en el almacenamiento en caché de contenido.
Colocar NGINX delante de una configuración de servidor existente como un servidor proxy inverso , seguido de usos adicionales, es un caso de uso central para NGINX, implementado por decenas de millones de sitios web en todo el mundo.
Existen ventajas específicas al utilizar NGINX como servidor proxy inverso Node.js , entre las que se incluyen:
Nota : Estos tutoriales explican cómo utilizar NGINX como un servidor proxy inverso en entornos Ubuntu 14.04 o CentOS , y son una descripción general útil para cualquiera que coloque NGINX delante de Node.js.
A medida que crece el uso de un sitio basado en Node.js, el servidor comenzará a mostrar la tensión. Hay dos cosas que debes hacer en este momento:
En realidad esto es fácil de hacer. Comience implementando NGINX como un servidor proxy inverso, como se describe en el consejo anterior . Esto facilita la implementación del almacenamiento en caché, el equilibrio de carga (cuando tienes varios servidores Node.js) y más.
El sitio web de Modulus, una plataforma de contenedores de aplicação , incluye un artículo útil sobre cómo optimizar el rendimiento de las aplicação Node.js con NGINX. Gracias a que Node.js se encarga de todo el trabajo por sí solo, el sitio del autor logró atender un promedio de casi 900 solicitudes por segundo. Con NGINX como servidor proxy inverso, sirviendo contenido estático, el mismo sitio atendió más de 1600 solicitudes por segundo, una mejora del rendimiento de casi el doble.
Duplicar el rendimiento le permite ganar tiempo para tomar medidas adicionales que permitan un mayor crecimiento, como revisar (y posiblemente mejorar) el diseño de su sitio, optimizar el código de su aplicação e implementar servidores de aplicação adicionales.
A continuación se muestra el código de configuración que funciona para un sitio web que se ejecuta en Modulus:
servidor { escucha 80;
nombre_del_servidor static-test-47242.onmodulus.net;
raíz /mnt/app;
índice index.html index.htm;
ubicación /static/ {
archivos_de_prueba $uri $uri/ =404;
}
ubicación /api/ {
contraseña_de_proxy http://node-test-45750.onmodulus.net;
}
}
Este artículo detallado de Patrick Nommensen de NGINX, Inc. explica cómo almacena en caché el contenido estático de su blog personal, que se ejecuta en la plataforma de blogs de código abierto Ghost, una aplicação Node.js. Aunque algunos de los detalles son específicos de Ghost, puedes reutilizar gran parte del código para otras aplicações Node.js.
Por ejemplo, en el bloque de ubicación
de NGINX, probablemente querrás eximir del almacenamiento en caché algún contenido. Por lo general, no es conveniente almacenar en caché la interfaz administrativa de una plataforma de blogs, por ejemplo. Aquí se muestra el código de configuración que deshabilita (o exime) el almacenamiento en caché de la interfaz administrativa de Ghost:
ubicación ~ ^/(?:ghost|signout) { proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://ghost_upstream;
add_header Cache-Control "sin caché, privado, sin almacenamiento,
debe revalidar, máximo de antigüedad = 0, comprobación posterior = 0, comprobación previa = 0";
}
Para obtener información general sobre cómo servir contenido estático, consulte la Guía de administración de NGINX Plus . La Guía del administrador incluye instrucciones de configuración, múltiples opciones para responder a intentos exitosos o fallidos de encontrar un archivo y enfoques de optimización para lograr un rendimiento aún más rápido.
El almacenamiento en caché de archivos estáticos en el servidor NGINX descarga significativamente el trabajo del servidor de aplicação Node.js, lo que le permite lograr un rendimiento mucho mayor.
La verdadera clave para lograr un rendimiento alto (es decir, casi ilimitado) para las aplicações Node.js es ejecutar múltiples servidores de aplicação y equilibrar las cargas entre todos ellos.
El equilibrio de carga de Node.js puede ser particularmente complicado porque Node.js permite un alto nivel de interacción entre el código JavaScript que se ejecuta en el navegador web y el código JavaScript que se ejecuta en el servidor de aplicação Node.js, con objetos JSON como medio de intercambio de datos. Esto implica que una sesión de cliente determinada se ejecuta continuamente en un servidor de aplicação específico y la persistencia de la sesión es inherentemente difícil de lograr con múltiples servidores de aplicação .
Una de las principales ventajas de Internet y la web es su alto grado de apátrida, lo que incluye la capacidad de que las solicitudes de los clientes sean atendidas por cualquier servidor con acceso al archivo solicitado. Node.js subvierte la falta de estado y funciona mejor en un entorno con estado, donde el mismo servidor responde constantemente a las solicitudes de cualquier cliente específico.
Este requisito se puede satisfacer mejor con NGINX Plus , en lugar de NGINX Open Source. Las dos versiones de NGINX son bastante similares, pero una diferencia importante es su soporte para diferentes algoritmos de equilibrio de carga.
NGINX admite métodos de equilibrio de carga sin estado:
Solo uno de estos métodos, IP Hash, envía de manera confiable las solicitudes de un cliente determinado al mismo servidor, lo que beneficia a las aplicações Node.js. Sin embargo, el hash de IP puede provocar fácilmente que un servidor reciba una cantidad desproporcionada de solicitudes, a expensas de otros servidores, como se describe en esta publicación de blog sobre técnicas de equilibrio de carga. Este método favorece la capacidad de mantener el estado a expensas de una asignación potencialmente subóptima de solicitudes entre los recursos del servidor.
A diferencia de NGINX, NGINX Plus admite la persistencia de sesión . Con la persistencia de sesión en uso, el mismo servidor recibe de manera confiable todas las solicitudes de un cliente determinado. Se maximizan las ventajas de Node.js, con su comunicación con estado entre cliente y servidor, y NGINX Plus, con su capacidad avanzada de equilibrio de carga.
De esta forma, puedes usar NGINX o NGINX Plus para soportar el equilibrio de carga entre múltiples servidores Node.js. Sin embargo, solo con NGINX Plus es posible lograr un rendimiento máximo de equilibrio de carga y un estado compatible con Node.js. Las comprobaciones del estado de la aplicação y las capacidades de monitorización integradas en NGINX Plus también son útiles aquí.
NGINX Plus también admite el vaciado de sesiones , lo que permite que un servidor de aplicação complete sin problemas las sesiones actuales después de una solicitud para que el servidor salga del servicio.
HTTP, en todas sus versiones, está diseñado para comunicaciones “pull”, donde el cliente solicita archivos al servidor. WebSocket es una herramienta para habilitar comunicaciones “push” y “push/pull”, donde el servidor puede enviar proactivamente archivos que el cliente no ha solicitado.
El protocolo WebSocket facilita una interacción más sólida entre el cliente y el servidor al tiempo que reduce la cantidad de datos transferidos y minimiza la latencia. Cuando es necesario, es posible lograr una conexión dúplex completa, en la que tanto el cliente como el servidor inician y reciben solicitudes según sea necesario.
El protocolo WebSocket tiene una interfaz JavaScript robusta y, como tal, se adapta naturalmente a Node.js como servidor de aplicação y, para aplicações web con volúmenes de transacciones moderados, también como servidor web. Cuando aumentan los volúmenes de transacciones, tiene sentido insertar NGINX entre los clientes y el servidor web Node.js, utilizando NGINX o NGINX Plus para almacenar en caché archivos estáticos y equilibrar la carga entre múltiples servidores de aplicação .
Node.js se utiliza a menudo junto con Socket.IO, una API WebSocket que se ha vuelto bastante popular para su uso junto con aplicações Node.js. Esto puede provocar que el puerto 80 (para HTTP) o el puerto 443 (para HTTPS) se saturen bastante y la solución es usar un proxy hacia el servidor Socket.IO. Puede utilizar NGINX como servidor proxy , como se describe anteriormente, y también obtener funcionalidad adicional, como almacenamiento en caché de archivos estáticos, equilibrio de carga y más.
A continuación se muestra el código para un archivo de aplicação de nodo server.js que escucha en el puerto 5000. Actúa como un servidor proxy (no un servidor web) y enruta las solicitudes al puerto adecuado:
var io = require('socket.io').listen(5000);
io.sockets.on('conexión', función (socket) {
socket.on('establecer apodo', función (nombre) {
socket.set('apodo', nombre, función () {
socket.emit('listo');
});
});
socket.on('msg', función () {
socket.get('apodo', función (err, nombre) {
console.log('Mensaje de chat de ', nombre);
});
});
});
Dentro de su archivo index.html , agregue el siguiente código para conectarse a su aplicação de servidor e instanciar un WebSocket entre la aplicação y el navegador del usuario:
<script src="/socket.io/socket.io.js"></script><script>// <![CDATA[
var socket = io(); // Tu código de inicialización aquí.
// ]]>
</script>
Para obtener instrucciones completas, incluida la configuración de NGINX, consulte nuestra publicación de blog sobre el uso de NGINX y NGINX Plus con Node.js y Socket.IO . Para obtener más información sobre posibles problemas arquitectónicos y de infraestructura para aplicações web de este tipo, consulte nuestra publicación de blog sobre aplicações web en tiempo real y WebSocket.
Cada vez más sitios utilizan SSL/TLS para proteger toda la interacción del usuario en el sitio. Depende de usted decidir si desea realizar este cambio y cuándo hacerlo, pero si lo hace, NGINX apoya la transición de dos maneras:
Entre los pasos de implementación que debe seguir se encuentran actualizar la URL en el archivo de configuración Node.js, establecer y optimizar conexiones seguras en su configuración NGINX y usar SPDY o HTTP/2 si lo desea. Agregar compatibilidad con HTTP/2 significa que las versiones del navegador que admiten HTTP/2 se comunican con su aplicação utilizando el nuevo protocolo; las versiones más antiguas del navegador continúan usando HTTP/1.x.
El siguiente código de configuración es para un blog Ghost que utiliza SPDY, como se describe aquí . Incluye funciones avanzadas como grapado OCSP. Para conocer las consideraciones sobre el uso de NGINX para la terminación SSL, incluida la opción de grapado OCSP, consulte aquí . Para obtener una descripción general de los mismos temas, consulte aquí .
Solo necesita realizar modificaciones menores para configurar su aplicação Node.js y actualizar de SPDY a HTTP/2, ahora o cuando desaparezca el soporte de SPDY a principios de 2016.
servidor { nombre_servidor dominio.com;
escuchar 443 ssl spdy;
comp_encabezados_spdy 6;
tiempo_espera_mantenimiento_spdy 300;
tiempo_espera_mantenimiento_300;
clave_certificado_ssl /etc/nginx/ssl/domain.key;
certificado_ssl /etc/nginx/ssl/domain.crt;
caché_sesión_ssl compartida:SSL:10m;
tiempo_espera_sesión_ssl 24h;
tamaño_búfer_ssl 1400;
grapado_ssl activado;
verificación_grapado_ssl activada;
certificado_confiable_ssl /etc/nginx/ssl/trust.crt; Resolver 8.8.8.8 8.8.4.4 válido=300s;
add_header Seguridad de Transporte Estricta 'max-age=31536000; includeSubDomains';
add_header Caché X $estado_caché_upstream;
ubicación / {
caché_proxy ESTÁTICO;
caché_proxy válido 200 30m;
caché_proxy válido 404 1m;
contraseña_proxy http://ghost_upstream;
encabezados_ignorados_proxy Caducidad de Aceleración X Caducidad de Control de Caché;
encabezados_ignorados_proxy Establecer Cookie;
encabezado_ocultar_proxy Establecer Cookie;
encabezado_ocultar_proxy Impulsado por X;
encabezado_configurado_proxy X-IP Real $dirección_remota; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
Caduca 10m;
}
ubicación /contenido/imágenes {
alias /ruta/a/fantasma/contenido/imágenes;
cierre_de_acceso;
caduca máx.;
}
ubicación /activos {
alias /ruta/a/fantasma/temas/uno-master/activos;
cierre_de_acceso;
caduca máx.;
}
ubicación /público {
alias /ruta/a/fantasma/construido/público;
cierre_de_acceso;
caduca máx.;
}
ubicación /fantasma/scripts {
alias /ruta/a/fantasma/núcleo/construido/scripts;
cierre_de_acceso;
caduca máx.;
}
ubicación ~ ^/(?:ghost|signout) {
encabezado_proxy X-Real-IP $dirección_remota;
encabezado_proxy Host $http_host;
contraseña_proxy http://ghost_upstream;
encabezado_adicional Control de caché "sin caché, privado, sin almacenamiento, debe revalidarse, máximo obsoleto=0, comprobación posterior=0, comprobación previa=0";
encabezado_proxy X-Proto-reenviado https;
}
}
Esta publicación de blog describe algunas de las mejoras de rendimiento más importantes que puede realizar en sus aplicações Node.js. Se centra en la incorporación de NGINX a su combinación de aplicação junto con Node.js, utilizando NGINX como un servidor proxy inverso, para almacenar en caché archivos estáticos, para equilibrar la carga, para proxyizar conexiones WebSocket y para finalizar los protocolos SSL/TLS y HTTP/2.
La combinación de NGINX y Node.js es ampliamente reconocida como una forma de crear nuevas aplicações compatibles con microservicios o agregar flexibilidad y capacidad a aplicações existentes basadas en SOA que usan Java o Microsoft .NET. Esta publicación le ayudará a optimizar sus aplicações Node.js y, si lo desea, a darle vida a la asociación entre Node.js y NGINX.
"Esta publicación de blog puede hacer referencia a productos que ya no están disponibles o que ya no reciben soporte. Para obtener la información más actualizada sobre los productos y soluciones F5 NGINX disponibles, explore nuestra familia de productos NGINX . NGINX ahora es parte de F5. Todos los enlaces anteriores de NGINX.com redirigirán a contenido similar de NGINX en F5.com.