Ir al contenido principal
Versión: 4.x

Escalando horizontalmente

Ahora que nuestra aplicación es resiliente a interrupciones temporales de red, veamos cómo podemos escalarla horizontalmente para poder soportar miles de clientes concurrentes.

nota
  • Escalado horizontal (también conocido como "scaling out") significa añadir nuevos servidores a tu infraestructura para hacer frente a nuevas demandas
  • Escalado vertical (también conocido como "scaling up") significa añadir más recursos (poder de procesamiento, memoria, almacenamiento, ...) a tu infraestructura existente

Primer paso: usemos todos los núcleos disponibles del host. Por defecto, Node.js ejecuta tu código Javascript en un solo hilo, lo que significa que incluso con una CPU de 32 núcleos, solo se usará un núcleo. Afortunadamente, el módulo cluster de Node.js proporciona una forma conveniente de crear un hilo worker por núcleo.

También necesitaremos una forma de reenviar eventos entre los servidores Socket.IO. Llamamos a este componente un "Adaptador".

El evento 'hello' se reenvía a los otros servidoresEl evento 'hello' se reenvía a los otros servidores

Así que instalemos el adaptador cluster:

npm install @socket.io/cluster-adapter

Ahora lo conectamos:

index.js
const express = require('express');
const { createServer } = require('node:http');
const { join } = require('node:path');
const { Server } = require('socket.io');
const sqlite3 = require('sqlite3');
const { open } = require('sqlite');
const { availableParallelism } = require('node:os');
const cluster = require('node:cluster');
const { createAdapter, setupPrimary } = require('@socket.io/cluster-adapter');

if (cluster.isPrimary) {
const numCPUs = availableParallelism();
// crear un worker por núcleo disponible
for (let i = 0; i < numCPUs; i++) {
cluster.fork({
PORT: 3000 + i
});
}

// configurar el adaptador en el hilo primario
return setupPrimary();
}

async function main() {
const app = express();
const server = createServer(app);
const io = new Server(server, {
connectionStateRecovery: {},
// configurar el adaptador en cada hilo worker
adapter: createAdapter()
});

// [...]

// cada worker escuchará en un puerto distinto
const port = process.env.PORT;

server.listen(port, () => {
console.log(`servidor corriendo en http://localhost:${port}`);
});
}

main();

¡Eso es todo! Esto creará un hilo worker por CPU disponible en tu máquina. Veámoslo en acción:

Como puedes ver en la barra de direcciones, cada pestaña del navegador está conectada a un servidor Socket.IO diferente, y el adaptador simplemente está reenviando los eventos chat message entre ellos.

consejo

Actualmente hay 5 implementaciones oficiales de adaptadores:

Así que puedes elegir el que mejor se adapte a tus necesidades. Sin embargo, ten en cuenta que algunas implementaciones no soportan la característica de Recuperación del estado de conexión, puedes encontrar la matriz de compatibilidad aquí.

nota

En la mayoría de los casos, también necesitarías asegurar que todas las solicitudes HTTP de una sesión Socket.IO lleguen al mismo servidor (también conocido como "sticky session"). Esto no es necesario aquí, ya que cada servidor Socket.IO tiene su propio puerto.

Más información aquí.

¡Y eso finalmente completa nuestra aplicación de chat! En este tutorial, hemos visto cómo:

  • enviar un evento entre el cliente y el servidor
  • difundir un evento a todos o un subconjunto de clientes conectados
  • manejar desconexiones temporales
  • escalar

¡Ahora deberías tener una mejor visión general de las características proporcionadas por Socket.IO. Ahora es tu turno de construir tu propia aplicación en tiempo real!

información

Puedes ejecutar este ejemplo directamente en tu navegador en: