node.js - deploy - Cómo escalar correctamente la aplicación nodejs en heroku usando clusters
procfile heroku node js (2)
El nodo tiene una capacidad limitada para escalar a diferentes tamaños de contenedor. Es de un solo subproceso, por lo que no puede aprovechar automáticamente los núcleos de CPU adicionales. Además, está basado en V8, que tiene un límite de memoria de aproximadamente 1,5 GB, por lo que tampoco puede aprovechar automáticamente la memoria adicional.
En cambio, las aplicaciones de Node.js deben dividir varios procesos para maximizar sus recursos disponibles. Esto se denomina "clustering" y es compatible con la API del clúster Node.js. Puede invocar la API de clúster directamente en su aplicación, o puede usar una de muchas abstracciones sobre la API.
Un buen artículo allí en heroku especifica cómo habilitar las concurrencias usando el módulo throng
Noté una advertencia en los registros de heroku diciendo últimamente que me parecía nuevo
web.1: se detectaron 512 MB de memoria disponible, 512 MB de límite por proceso (WEB_MEMORY)
web.1: recomendando WEB_CONCURRENCY = 1
Hice algunas investigaciones y encontré este artículo de clúster , que es la forma "predeterminada" de usar clusters en nodejs, pero contradice totalmente con un artículo recién actualizado que contiene esta nueva variable de entorno WEB_CONCURRENCY
y con una sugerencia de tamaño diferente para cada dyno (que es mucho más pequeño, por cierto)
El primer enlace es de julio de 2014 y solía ser la forma recomendada de hacer las cosas. Sin embargo, los dynos de Heroku están bastante centrados en la memoria, y es muy fácil exceder la asignación de memoria asignada cuando se usa la cantidad máxima de núcleos por CPU (como sugiere el primer artículo).
En cambio, la nueva recomendación es perfilar su aplicación y calcular cuánta memoria se requiere por proceso. Establezca una variable de entorno WEB_MEMORY
a este valor y luego actualice su código de clúster a lo siguiente:
var cluster = require(''cluster'');
var numWorkers = process.env.WEB_CONCURRENCY;
if(cluster.isMaster) {
// Master process: fork our child processes
for (var i = 0; i < numWorkers; i++) {
cluster.fork();
}
// Respawn any child processes that die
cluster.on(''exit'', function() {
cluster.fork();
});
} else {
// Child process, put app initialisation code here.
}
Al usar la variable WEB_MEMORY
, Heroku puede generar un valor de WEB_CONCURRENCY
dependiendo del tamaño del WEB_CONCURRENCY
que esté ejecutando, y por lo tanto, bifurque el número correcto de procesos para asegurarse de que su aplicación no exceda la asignación de memoria.
Como un lado, si excedes la asignación de memoria (512MB por dyno para un dyno 1x), se usará el espacio de intercambio para el exceso. Esto ralentizará su aplicación, lo que hará que los tiempos de solicitud aumenten y, en general, contribuirá a la lentitud. Si excedes demasiado el uso de la memoria (aproximadamente tres veces la asignación), Heroku reiniciará tu banco de pruebas.