くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Node.jsでgraceful shutdown

Node.jsでgraceful shutdownするときは、
どうすればいいのかなと、いろいろ調べてみたときの備忘録(*´ω`*)

graceful shutdownとは

「サーバーが不意に終了しても、終わる前にちゃんと後片付けをすること」です。
引用: 欅樹雑記: Node.jsサーバーのgraceful shutdownまとめ

プロセスをkillしたり、Ctrl+Cしたり、ターミナルを閉じたりしたときでも、
サーバをcloseしたり、実行中の処理を待ってから終了したりするやつ。

プロセスの終了時に終了シグナルが送られるので、
受け取ったシグナルに応じて、終了時の処理をおこなう感じ。

シグナルの種類

主だったシグナルはこのあたり。

名前 番号 動作(※) 意味
SIGHUP 1 Term 制御端末の切断(ハングアップ)、仮想端末の終了
SIGINT 2 Term キーボードからの割り込みシグナル(通常は[CTRL]+[C])
SIGTERM 15 Term 終了シグナル(「kill」コマンドのデフォルトシグナル)
SIGKILL 9 Term 強制終了シグナル(KILLシグナル)

シグナルを受け取ったときの処理

Node.jsのprocessでEventを受け取る感じで対応する。

// Terminalを閉じたとき
process.on("SIGHUP", () => {
  process.exit(0); //プロセスの正常終了
});

// Ctrl + Cで終了したとき
process.on("SIGINT", () => {
  process.exit(0); //プロセスの正常終了
});

// killで終了したとき
process.on("SIGTERM", () => {
  process.exit(0); //プロセスの正常終了
});

// kill -9 で終了したとき
process.on("SIGKILL", () => {
  process.exit(0); //プロセスの正常終了
});

// process.exit時
process.on("exit", exitCode => {
  // ...
});

// exitの前
process.once('beforeExit', () => {
  // ...
});

関連パッケージ

npmで「graceful shutdown」と検索するといろいろ出てくる。

対応しているシグナルの種類なども異なるので注意。
いずれも小さなソースなので読んでみても、自前で実装してもよい感じ。

自前で実装しているOSSも多いので、
シグナルで検索してみるといろいろ参考になる。

おまけ: Linuxのシグナルの種類

名前 番号 動作(※) 意味
SIGHUP 1 Term 制御端末の切断(ハングアップ)、仮想端末の終了
SIGINT 2 Term キーボードからの割り込みシグナル(通常は[CTRL]+[C])
SIGQUIT 3 Core キーボードによる中止シグナル(通常は[CTRL]+[\])
SIGTERM 15 Term 終了シグナル(「kill」コマンドのデフォルトシグナル)
SIGFPE 8 Core 不正な浮動小数点演算(ゼロ除算やオーバーフローなど)の発生
SIGKILL 9 Term 強制終了シグナル(KILLシグナル)
SIGSEGV 11 Core 不正なメモリ参照の発生
SIGPIPE 13 Term 読み手のいないパイプへの書き込み(通常はこのシグナルを受け取ると即時終了する)
SIGALRM 14 Term タイマー(Alarm)による終了
SIGCHLD 17 Ignore 子プロセスの状態(終了、停止または再開)が変わった
SIGCONT 18 Cont 一時停止しているジョブへの再開シグナル
SIGSTOP 19 Stop 一時停止シグナル
SIGTSTP 20 Stop 端末からの一時停止シグナル(通常は[CTRL]+[Z])
SIGTTIN 21 Stop バックグラウンドジョブ/プロセスのキーボード入力待ち
SIGTTOU 22 Stop バックグラウンドジョブ/プロセスの端末出力待ち
SIGXCPU 24 Core CPU時間制限を越えた
SIGXFSZ 25 Core ファイルサイズ制限を越えた
SIGWINCH 28 Ignore ウィンドウのサイズが変更された

以上!! これでNode.jsでもGracefulにShutdownできるぞ。。(´ω`)

参考にしたサイトさま