Tema 3

Despliegue de una aplicación clusterizada con Node Express

Primero sin Cluster


const express = require("express");
const app = express();
const port = 3000;
app.get("/", (req, res) => {
    res.send("Hello World!");
});
app.get("/api/:n", function (req, res) {
    let n = parseInt(req.params.n);
    let count = 0;

    if (n > 5000000000) n = 5000000000;

    for (let i = 0; i <= n; i++) {
        count += i;
    }

    res.send(`Final count is ${count}`);
});

app.listen(port, () => {
    console.log(`App listening on port ${port}`);
});

npm init

npm install express

Iniciamos la aplicación:


node pruebaSinCluster.js

Para comprobar accedemos a http://IP-maq-virtual:3000

Ahora comprobamos con 2 valores diferentes en 2 pestañas de navegador abiertas:

Podemos comprobar que con el n=5000000 tarda mucho más, porque la aplicación no está clusterizada.

Con cluster


const express = require("express");
const port = 3000;
const cluster = require("cluster");
const totalCPUs = require("os").cpus().length;

if (cluster.isMaster) {
    console.log(`Number of CPUs is ${totalCPUs}`);
    console.log(`Master ${process.pid} is running`);

    // Fork workers.
    for (let i = 0; i < totalCPUs; i++) {
        cluster.fork();
    }

    cluster.on("exit", (worker, code, signal) => {
        console.log(`worker ${worker.process.pid} died`);
        console.log("Let's fork another worker!");
        cluster.fork();
    });
} else {
    const app = express();
    console.log(`Worker ${process.pid} started`);

    app.get("/", (req, res) => {
        res.send("Hello World!");
    });

    app.get("/api/:n", function (req, res) {
        let n = parseInt(req.params.n);
        let count = 0;

        if (n > 5000000000) n = 5000000000;

        for (let i = 0; i <= n; i++) {
            count += i;
        }

        res.send(`Final count is ${count}`);
    });

    app.listen(port, () => {
        console.log(`App listening on port ${port}`);
    });
}

Ahora hacemos el mismo procedimiento que la aplicación sin cluster y comprobamos la velocidad de carga de esta aplicación Clusterizada.

Métricas de rendimiento

Instalamos loadtest que nos permite simular una gran cantidad de conexiones simultáneas a nuestra API para que podamos medir su rendimiento.


npm install -g loadtest

Mientras ejecutamos la aplicación, en otro terminal realizamos la siguiente prueba de carga:


loadtest http://localhost:3000/api/500000 -n 1000 -c 100

El comando anterior enviará 1000 solicitudes a la URL dada, de las cuales 100 son concurrentes.

Ahora detenemos la aplicación sin clusters y ejecutamos:


node nombre_aplicacio_cluster.js 

Ejecutaremos exactamente las mismas pruebas con el objetivo de realizar una comparación.