java - parse - nodejs res
¿Cómo escalar NodeJS linealmente en múltiples núcleos? (2)
Estoy haciendo una prueba rápida de rendimiento para NodeJS vs. Java. El caso de uso simple elegido es consultar una sola tabla en la base de datos MySQL. Los resultados iniciales fueron los siguientes:
Platform | DB Connections | CPU Usage | Memory Usage | Requests/second
==============================|================|===========|===============|================
Node 0.10/MySQL | 20 | 34% | 57M | 1295
JBoss EAP 6.2/JPA | 20 | 100% | 525M | 4622
Spring 3.2.6/JDBC/Tomcat 7.0 | 20 | 100% | 860M | 4275
Tenga en cuenta que la CPU y el uso de la memoria de Node son mucho más bajos que Java, ¡pero el rendimiento también es aproximadamente un tercio! Luego me di cuenta de que Java estaba utilizando los cuatro núcleos en mi CPU, mientras que Node se ejecutaba en un solo núcleo. Así que cambié el código del nodo para incorporar el módulo de clúster y ahora estaba utilizando los cuatro núcleos. Aquí están los nuevos resultados:
Platform | DB Connections | CPU Usage | Memory Usage | Requests/second
==============================|================|===========|===============|================
Node 0.10/MySQL (quad core) | 20 (5 x 4) | 100% | 228M (57 x 4) | 2213
Tenga en cuenta que el uso de la CPU y la memoria ahora ha aumentado proporcionalmente, pero el rendimiento solo ha aumentado un 70%. Esperaba un aumento de cuatro veces, superando el rendimiento de Java. ¿Cómo puedo dar cuenta de la discrepancia? ¿Qué puedo hacer para aumentar el rendimiento linealmente?
Aquí está el código para utilizar múltiples núcleos:
if (Cluster.isMaster) {
var numCPUs = require("os").cpus().length;
for (var i = 0; i < numCPUs; i++) {
Cluster.fork();
}
Cluster.on("exit", function(worker, code, signal) {
Cluster.fork();
});
}
else {
// Create an express app
var app = Express();
app.use(Express.json());
app.use(enableCORS);
app.use(Express.urlencoded());
// Add routes
// GET /orders
app.get(''/orders'', OrderResource.findAll);
// Create an http server and give it the
// express app to handle http requests
var server = Http.createServer(app);
server.listen(8080, function() {
console.log(''Listening on port 8080'');
});
}
Estoy utilizando el controlador node-mysql para consultar la base de datos. El conjunto de conexiones se establece en 5 conexiones por núcleo, sin embargo, eso no hace ninguna diferencia. Si configuro este número en 1 o 20, obtengo aproximadamente el mismo rendimiento.
var pool = Mysql.createPool({
host: ''localhost'',
user: ''bfoms_javaee'',
password: ''bfoms_javaee'',
database: ''bfoms_javaee'',
connectionLimit: 5
});
exports.findAll = function(req, res) {
pool.query(''SELECT * FROM orders WHERE symbol="GOOG"'', function(err, rows, fields) {
if (err) throw err;
res.send(rows);
});
};
Intente configurar la variable de entorno export NODE_CLUSTER_SCHED_POLICY="rr"
. Según esta publicación del blog .
Por lo que veo, no estás comparando solo plataformas, sino también los marcos. Probablemente desee eliminar el efecto de marco e implementar un servidor HTTP simple. Por ejemplo, todos esos middlewares en la aplicación Express se suman a la latencia. Además, ¿se aseguró de que las bibliotecas de Java no almacenen en caché los datos solicitados con frecuencia, lo que mejoraría significativamente el rendimiento?
Otra cosa a considerar es que el módulo http
incorporado en Nodo (por lo tanto, cualquier biblioteca construida sobre él, incluyendo node-mysql
) mantiene un grupo de conexiones internas a través de la clase Agente (para no confundirse con el grupo de conexiones MySQL), por lo que que puede utilizar HTTP keep-alives. Esto ayuda a aumentar el rendimiento cuando se ejecutan muchas solicitudes en el mismo servidor en lugar de abrir una conexión TCP, realizar una solicitud HTTP, obtener una respuesta, cerrar la conexión TCP y repetir. Por lo tanto, las conexiones TCP pueden ser reutilizadas.
De forma predeterminada, el Agente HTTP solo abrirá 5 conexiones simultáneas a un único host, como su servidor MySQL. Puedes cambiar esto fácilmente de la siguiente manera:
var http = require(''http'');
http.globalAgent.maxSockets = 20;
Teniendo en cuenta estos cambios, vea qué mejoras puede obtener.
Otra idea es verificar que el grupo de conexiones de MySQL se usa correctamente al verificar los registros de MySQL cuando se abren las conexiones y cuando se cierran. Si se abren con frecuencia, es posible que deba aumentar el valor de tiempo de espera de inactividad en node-mysql.