Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8835

(小ネタ)Node.jsのWebアプリでclusterを使いながら定期的に子プロセスを再起動させる

$
0
0

Node.jsでサーバサイドWebアプリを開発中、なぜかメモリリークがあるライブラリに遭遇してしまったので、ワークアラウンドとして、定期的にプロセスを再起動させて、メモリリークの問題を緩和したいと思いました。

サーバサイド

http://0.0.0.0:10080をリスンするプロセスが4つ立ち上がり、5秒未満で子プロセスを停止させ、その後に再起動します。(実用上は、もっと長い時間でプロセスを殺すべきです。)

src/index.js
constcluster=require("cluster");consthttp=require("http");constsleep=time=>newPromise(done=>setTimeout(done,time));constclusterCount=4;constportNumber=10080;if(cluster.isMaster){constspawnProcess=()=>{// プロセスを終了させるまでの時間: 0 〜 5000 msecconstttl=~~(5000*Math.random());constchild=cluster.fork();lettimeout;child.on("listening",()=>{// 指定時間で終了(Graceful kill)させるconsole.log(`誕生! 死まで ${ttl} msec.`);timeout=setTimeout(()=>{console.log(`死: ${child.id}`);child.kill();},ttl);});child.on("disconnect",()=>{// 別の理由で死んだ場合はkillをキャンセルif(timeout){clearTimeout(timeout);}});child.on("exit",()=>{// 子プロセスが終了したら代わりのものを1つ起動するspawnProcess();});};// 子プロセスを複数起動するfor(leti=0;i<clusterCount;i++){spawnProcess();}}if(cluster.isWorker){// Express や Koa など好きに使いましょうhttp.createServer(async(req,res)=>{// リクエスト終了までやや時間がかかる設定awaitsleep(1000);res.writeHead(200);res.end("Request done\n");}).listen(portNumber);}

起動すると、下記のようなログを吐きながら、プロセスの終了と生成を延々と繰り返します。

誕生! 死まで 2712 msec.
誕生! 死まで 3984 msec.
誕生! 死まで 4297 msec.
誕生! 死まで 1547 msec.
死: 4
誕生! 死まで 4276 msec.
死: 2
:
:

テスト

abコマンドできちんとリクエストが中断されずにいるか、テストしてみます、

$ ab -c 20 -n 500 http://localhost:10080/
This is ApacheBench, Version 2.3 <$Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Finished 500 requests


Server Software:        
Server Hostname:        localhost
Server Port:            10080

Document Path:          /
Document Length:        13 bytes

Concurrency Level:      20
Time taken for tests:   26.226 seconds
Complete requests:      500
Failed requests:        0
Total transferred:      44000 bytes
HTML transferred:       6500 bytes
Requests per second:    19.07 [#/sec] (mean)
Time per request:       1049.029 [ms] (mean)
Time per request:       52.451 [ms] (mean, across all concurrent requests)
Transfer rate:          1.64 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   1.0      0       7
Processing:  1000 1008   5.4   1007    1025
Waiting:     1000 1007   4.7   1006    1023
Total:       1000 1008   5.5   1007    1025

Percentage of the requests served within a certain time (ms)
  50%   1007
  66%   1010
  75%   1012
  80%   1013
  90%   1016
  95%   1019
  98%   1020
  99%   1022
 100%   1025 (longest request)

特に何も問題なくリクエスト処理は完了しているようです。

Complete requests:      500
Failed requests:        0

まとめ

  • cluster でマルチプロセス化できるし、定期的にプロセスを再起動して、健全性を保つことができるはず
    • こういうゴミ掃除はマルチスレッドモデルだとできなさそう

Viewing all articles
Browse latest Browse all 8835

Trending Articles