dak ブログ

python、rubyなどのプログラミング、MySQL、サーバーの設定などの備忘録。レゴの写真も。

cluster によるマルチプロセスでの express の http サーバ

2022-04-09 14:15:22 | Node.js
cluster を使うと、マルチプロセスで処理を行うことができます。
cluster では、親となる master が fork() して子の worker を生成します。

以下では、woker が http リクエストを処理し、master は worker が異常終了した場合に、
再度 worker を生成するようにしています。
import os from 'os';
import process from 'process';
import cluster from 'cluster';
import express from 'express';

const port = 8103;
const pid = process.pid;
console.log(`pid: ${pid}`);

if (cluster.isMaster) {
  console.log(`master: ${pid}`);
  const num_cpus = os.cpus().length;
  for (let i = 0; i < num_cpus * 3; i++) { // CPU がひとつのため x 3 している
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    const wpid = worker.process.pid;
    console.log(`exit: ${wpid}`);
    cluster.fork();
  });
}
else {
  const app = express();

  app.get('/', (http_req, http_res) => {
    console.log(`receive: ${pid}`);
    http_res.send(`worker_pid: ${pid}\n`);
  });

  app.listen(port, () => {
    console.log(`http server start: ${pid}`);
  });
}

■実行例
最初にプロセスIDを出力するようにしているため、master のプロセスIDが出力されます。
pid: 9394
master: 9394

続いて、worker のプロセスID が出力され、その後 http サーバの初期化が行われます。
pid: 9401
pid: 9402
pid: 9403
http server start: 9401
http server start: 9402
http server start: 9403

■http リクエスト送信
http リクエストを何度か送信すると、http クライアントにはリクエストを処理した worker のプロセスIDが返却されます。
curl 'http://localhost:8103/'
-->
pid: 9403

curl 'http://localhost:8103/'
-->
pid: 9402

curl 'http://localhost:8103/'
-->
pid: 9401

■worker を kill
pid=9401 の worker を kill します。
kill -9 9401

すると、master が新たに worker を生成します。
exit: 9401
pid: 9430
http server start: 9430

http リクエストを送信すると、新たな worker もレスポンスを返します。
curl 'http://localhost:8103/'
-->
pid: 9430

■master を kill
master を kill すると、worker も終了します。
kill -9 9394
ps
    PID TTY          TIME CMD
   5923 pts/1    00:00:00 bash
   9565 pts/1    00:00:00 ps