[javascript] Express.js에서의 웹 서버 클러스터링 방법

Express.js는 Node.js 위에서 동작하는 웹 애플리케이션 프레임워크로, 개발자들이 웹 서버를 빠르고 쉽게 구축할 수 있게 도와줍니다. 하지만, 실제 서비스 환경에서는 단일 서버로만 운영하기보다는 웹 서버 클러스터링을 통해 서버의 성능과 가용성을 높일 수 있습니다.

웹 서버 클러스터링은 여러 대의 서버를 하나의 그룹으로 구성하여 부하 분산, 장애 대응 등을 위해 트래픽을 분산시키는 것을 의미합니다. Express.js에서 웹 서버 클러스터링을 구현하는 방법을 살펴보도록 하겠습니다.

클러스터 모듈 사용하기

Node.js의 내장 모듈인 cluster를 사용하여 Express.js 애플리케이션을 클러스터링할 수 있습니다. 클러스터 모듈을 사용하면 간단한 코드로 다중 프로세스로 웹 서버를 실행할 수 있습니다.

const cluster = require('cluster');
const os = require('os');
const express = require('express');

const numCPUs = os.cpus().length;
const port = 3000;

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

  // CPU 코어 수만큼 워커 생성
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  // 워커가 종료될 경우 새로운 워커 생성
  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
    cluster.fork();
  });
} else {
  const app = express();

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

  app.listen(port, () => {
    console.log(`Worker ${process.pid} started`);
  });
}

위 코드에서 isMaster를 통해 마스터 프로세스와 워커 프로세스를 구분합니다. 마스터 프로세스는 워커를 생성하고 관리하는 역할을 맡으며, 워커 프로세스는 실제로 Express.js 애플리케이션을 실행합니다.

사용자의 요청 처리하기

클러스터링된 Express.js 서버는 여러 워커 프로세스로 분산되므로 사용자의 요청이 여러 워커로 동시에 들어올 수 있습니다. 이때, 각 워커는 독립적으로 요청을 처리해야 합니다.

Express.js에서는 cluster.worker 객체를 통해 현재 실행 중인 워커를 식별할 수 있습니다. 이를 활용하여 각 워커가 요청을 독립적으로 처리하도록 할 수 있습니다.

const cluster = require('cluster');
const os = require('os');
const express = require('express');

const numCPUs = os.cpus().length;
const port = 3000;

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

  // CPU 코어 수만큼 워커 생성
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  // 워커가 종료될 경우 새로운 워커 생성
  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
    cluster.fork();
  });
} else {
  const app = express();

  app.get('/', (req, res) => {
    console.log(`Request handled by worker ${cluster.worker.id}`);
    res.send('Hello World!');
  });

  app.listen(port, () => {
    console.log(`Worker ${process.pid} started`);
  });
}

위 코드에서 cluster.worker.id를 통해 각 워커의 식별자를 출력하고 있습니다. 이를 활용하여 각 워커가 요청을 처리하는 것을 확인할 수 있습니다.

결론

Express.js에서의 웹 서버 클러스터링을 통해 서버의 성능과 가용성을 높일 수 있습니다. 클러스터 모듈을 사용하여 다중 프로세스로 Express.js 애플리케이션을 실행하고, 각 워커가 독립적으로 요청을 처리하도록 구현할 수 있습니다. 이를 통해 안정적이고 확장 가능한 웹 애플리케이션을 개발할 수 있습니다.

참고 자료: