Node.jsをforeverモジュールでデーモン化する
foreverモジュールを使用した時のメモです。
2年前くらいのネタです。
Node.jsはシングルスレッドのため、
エラー発生時にハンドリングされていないと止まってしまいます。
foreverを使用してデーモン化することで
エラー発生時に自動起動することができます。
インストール
npmでインストールします。
依存関係確認。
# npm view forever dependencies { cliff: '~0.1.9', clone: '^1.0.2', colors: '~0.6.2', flatiron: '~0.4.2', 'forever-monitor': '~1.6.0', nconf: '~0.6.9', nssocket: '~0.5.1', 'object-assign': '^3.0.0', optimist: '~0.6.0', 'path-is-absolute': '~1.0.0', prettyjson: '^1.1.2', shush: '^1.0.0', timespan: '~2.3.0', utile: '~0.2.1', winston: '~0.8.1' }
インストール。
npm installで-gオプションを指定した場合はグローバルインストールとなり、
どこからでもコマンドが呼び出せるようになります。
# npm install -g forever
確認
# ll /usr/local/nodejs/lib/node_modules/ 合計 8 drwxr-xr-x. 6 nobody root 4096 1月 18 01:28 forever drwxr-xr-x. 9 root root 4096 1月 18 00:13 npm # which forever /usr/local/nodejs/bin/forever
起動、停止
起動はforever startでモジュールを指定するだけ。
# forever start test.js warn: --minUptime not set. Defaulting to: 1000ms warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms info: Forever processing file: test.js
forever listで状態確認ができます。
# forever list info: Forever processes running data: uid command script forever pid id logfile uptime data: [0] ugJf /usr/local/nodejs/bin/node test.js 75127 75132 /root/.forever/ugJf.log 0:0:0:9.317
停止は複数の方法があります。
forever listで表示されるインデックスを指定します。
上記の場合は[0]がインデックスになります。
# forever stop 0 info: Forever stopped process: uid command script forever pid id logfile uptime [0] ugJf /usr/local/nodejs/bin/node test.js 75127 75132 /root/.forever/ugJf.log 0:0:0:32.77
もしくはuidを指定します。
# forever stop ugJf
もしくはpidを指定。
# forever stop 75132
もしくはモジュール名を指定。
# forever stop test.js
確認してみると止まっています。
# forever list
info: No forever processes running
自動起動確認
こんなjsを用意します。
アクセスすると、dummy()メソッドが見つからず異常終了します。
test.js
var http = require('http'); http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello forever\n'); dummy(); }).listen(8090, '127.0.0.1');
普通に起動してみます。
# node test.js
アクセスしてみると
# telnet localhost 8090 Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. GET / HTTP/1.0 HTTP/1.1 200 OK Content-Type: text/plain Date: Sun, 17 Jan 2016 17:20:31 GMT Connection: close Hello forever Connection closed by foreign host.
エラーを出力して異常終了します。
/opt/node/test.js:7 dummy(); ^ ReferenceError: dummy is not defined at Server.<anonymous> (/opt/node/test.js:7:2) at emitTwo (events.js:87:13) at Server.emit (events.js:172:7) at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:528:12) at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23)
次にforeverで起動してみます。
# forever start test.js warn: --minUptime not set. Defaulting to: 1000ms warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms info: Forever processing file: test.js
起動を確認。
# forever list info: Forever processes running data: uid command script forever pid id logfile uptime data: [0] 5atb /usr/local/nodejs/bin/node test.js 76055 76060 /root/.forever/5atb.log 0:0:0:3.190
さっきと同じようにアクセスしてみます。
# telnet localhost 8090
確認してみると落ちずに起動しています。
pidが新しくなっているのがわかります。
# forever list info: Forever processes running data: uid command script forever pid id logfile uptime data: [0] 5atb /usr/local/nodejs/bin/node test.js 76055 76071 /root/.forever/5atb.log 0:0:0:2.624
foreverのログを確認してみると、発生したエラーを確認できます。
# cat /root/.forever/5atb.log /opt/node/test.js:7 dummy(); ^ ReferenceError: dummy is not defined at Server.<anonymous> (/opt/node/test.js:7:2) at emitTwo (events.js:87:13) at Server.emit (events.js:172:7) at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:528:12) at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23) error: Forever detected script exited with code: 1 error: Script restart attempt #1
-mオプションで起動回数を指定できます。
回数には最初の起動も含まれるので、
-m 3の場合、自動起動は2回されます。
# forever start -m 3 test.js warn: --minUptime not set. Defaulting to: 1000ms warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms info: Forever processing file: test.js
アクセス1回目。
# telnet localhost 8090
ログを確認。エラーが発生しています。
# cat /root/.forever/gH8N.log /opt/node/test.js:7 dummy(); ^ ReferenceError: dummy is not defined at Server.<anonymous> (/opt/node/test.js:7:2) at emitTwo (events.js:87:13) at Server.emit (events.js:172:7) at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:528:12) at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23) error: Forever detected script exited with code: 1 error: Script restart attempt #1
自動起動により起動しています。
# forever list info: Forever processes running data: uid command script forever pid id logfile uptime data: [0] gH8N /usr/local/nodejs/bin/node test.js 76227 76247 /root/.forever/gH8N.log 0:0:0:1.929
アクセス2回目。
# telnet localhost 8090
ログを確認。エラーが2回発生しています。
# cat /root/.forever/gH8N.log /opt/node/test.js:7 dummy(); ^ ReferenceError: dummy is not defined at Server.<anonymous> (/opt/node/test.js:7:2) at emitTwo (events.js:87:13) at Server.emit (events.js:172:7) at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:528:12) at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23) error: Forever detected script exited with code: 1 error: Script restart attempt #1 /opt/node/test.js:7 dummy(); ^ ReferenceError: dummy is not defined at Server.<anonymous> (/opt/node/test.js:7:2) at emitTwo (events.js:87:13) at Server.emit (events.js:172:7) at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:528:12) at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23) error: Forever detected script exited with code: 1 error: Script restart attempt #2
自動起動により起動しています。
# forever list info: Forever processes running data: uid command script forever pid id logfile uptime data: [0] gH8N /usr/local/nodejs/bin/node test.js 76227 76259 /root/.forever/gH8N.log 0:0:0:2.150
アクセス3回目。
# telnet localhost 8090
ログを確認。エラーが3回発生しています。
# cat /root/.forever/gH8N.log /opt/node/test.js:7 dummy(); ^ ReferenceError: dummy is not defined at Server.<anonymous> (/opt/node/test.js:7:2) at emitTwo (events.js:87:13) at Server.emit (events.js:172:7) at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:528:12) at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23) error: Forever detected script exited with code: 1 error: Script restart attempt #1 /opt/node/test.js:7 dummy(); ^ ReferenceError: dummy is not defined at Server.<anonymous> (/opt/node/test.js:7:2) at emitTwo (events.js:87:13) at Server.emit (events.js:172:7) at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:528:12) at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23) error: Forever detected script exited with code: 1 error: Script restart attempt #2 /opt/node/test.js:7 dummy(); ^ ReferenceError: dummy is not defined at Server.<anonymous> (/opt/node/test.js:7:2) at emitTwo (events.js:87:13) at Server.emit (events.js:172:7) at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:528:12) at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23) error: Forever detected script exited with code: 1
確認するとSTOPPEDに変わりました。
自動起動せずに停止しています。
# forever list info: Forever processes running data: uid command script forever pid id logfile uptime data: [0] gH8N /usr/local/nodejs/bin/node test.js 76227 76259 /root/.forever/gH8N.log STOPPED
起動していないのでアクセスできません。
# telnet localhost 8090 Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... telnet: connect to address 127.0.0.1: Connection refused
終わり。