[Node.js] PM2を用いて本番環境でNodeJSアプリを動かす
こんにちは、@yoheiMuneです。
今日は、PM2というNode.jsを本番環境で起動するための便利なツールを、紹介したいと思います。
同様の本番環境で使える起動ツールとしては、foreverなどがありますが、最近ではPM2が便利でよく使われている印象です。
https://github.com/yoheiMune/node-playground/tree/master/010-pm2
今回は、以下のようなExpress4で作成された簡単なアプリケーションを例に、話を進めます。
この機能で、複数インスタンスを同時に立ち上げることで、マシンリソースを上限まで使うことができるようになります。具体的には、以下のように起動します。
上記の設定ファイルを用いて起動するには、以下のように行います。
http://pm2.keymetrics.io/docs/usage/quick-start/
最後になりますが本ブログでは、Linux・インフラ・開発環境・Python・フロントエンド・Go言語・Node.js・Swift・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSやTwitterをフォローして頂けると幸いです ^ ^。
最後までご覧頂きましてありがとうございました!
今日は、PM2というNode.jsを本番環境で起動するための便利なツールを、紹介したいと思います。
目次
PM2とは
PM2とは、Node.js製のWebアプリケーションを動かすための仕組みの一つです。例えば、Express4などで作成したアプリ(app.js)を動かしたい場合に普通だと、$ node app.jsとして起動しますが、PM2を用いると、
$ pm2 start app.jsのような形式でWebサービスを起動することができます。
node app.js
での起動は非常にシンプルですが、以下のような問題点があります。- 基本的にはCPU1コアしか使えず、マルチコアに対応するのに手間がかかる
- ログ出力や状態チェックなど自前で作る必要がある
- その他、本番運用のための細かな手間がある
同様の本番環境で使える起動ツールとしては、foreverなどがありますが、最近ではPM2が便利でよく使われている印象です。
今回のコードの置き場
以下におきましたので、必要あればご参照いただけたら幸いです。https://github.com/yoheiMune/node-playground/tree/master/010-pm2
今回は、以下のようなExpress4で作成された簡単なアプリケーションを例に、話を進めます。
// app.js const express = require('express'); app = express(); app.get('/', (req, res) => { res.send('Hello from index.'); }); app.listen(3000, () => { console.log('Express app starts, linstening port on 3000.') });
PM2のインストール
npm
から簡単にインストールすることが可能です。# PM2をインストール $ npm install -g pm2インストール後に、以下のコマンドが認識されていればOKです。
$ pm2
PM2を使う
それではここから、pm2の基本的な使い方を見てみたいと思います。起動する
起動するにはstart
コマンドを利用します。# pm2 start [スクリプトファイルパス] $ pm2 start app.js [PM2] Starting /Users/munesadayohei/git/node-playground/010-pm2/app.js in fork_mode (1 instance) [PM2] Done. ┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │ ├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤ │ app │ 0 │ fork │ 42728 │ online │ 0 │ 0s │ 0% │ 15.3 MB │ disabled │ └──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘ # --nameオプションをつけると、起動するアプリに名前をつけることができます。 # 今後の管理にも使うので、基本的には名前を明示的につけるのが良いです。 $ pm2 start app.js --name myapp [PM2] Starting /Users/munesadayohei/git/node-playground/010-pm2/app.js in fork_mode (1 instance) [PM2] Done. ┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │ ├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤ │ myapp │ 0 │ fork │ 42882 │ online │ 0 │ 0s │ 0% │ 13.4 MB │ disabled │ └──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
再起動する
デプロイなどでコードが変わる場合に、restart
コマンドでサーバーを再起動して、変更を取り込むことができます。# pm2 restart [アプリ名] $ pm2 restart myapp [PM2] Applying action restartProcessId on app [myapp](ids: 0) [PM2] [myapp](0) ✓ ┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │ ├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤ │ myapp │ 0 │ fork │ 43059 │ online │ 1 │ 0s │ 0% │ 15.2 MB │ disabled │ └──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘ここで
restart
が1
に増えているからも、再起動されたことがわかります。停止する
停止するためにはstop
コマンドを利用します。# pm2 stop [アプリ名] $ pm2 stop myapp [PM2] Applying action stopProcessId on app [myapp](ids: 0) [PM2] [myapp](0) ✓ ┌──────────┬────┬──────┬─────┬─────────┬─────────┬────────┬─────┬────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │ ├──────────┼────┼──────┼─────┼─────────┼─────────┼────────┼─────┼────────┼──────────┤ │ myapp │ 0 │ fork │ 0 │ stopped │ 1 │ 0 │ 0% │ 0 B │ disabled │ └──────────┴────┴──────┴─────┴─────────┴─────────┴────────┴─────┴────────┴──────────┘ Use `pm2 show` to get more details about an app
ログの確認
logs
コマンドを用いることで、出力されているログを確認することができます。# pm2 logs [アプリ名] $ pm2 logs myapp [TAILING] Tailing last 15 lines for [myapp] process (change the value with --lines option) /Users/munesadayohei/.pm2/logs/myapp-error-0.log last 15 lines: /Users/munesadayohei/.pm2/logs/myapp-out-0.log last 15 lines: 0|myapp | Express app starts, linstening port on 3000. 0|myapp | Express app starts, linstening port on 3000.
モニタリング
monit
コマンドを使うと、起動しているアプリのモニタリング(ログの確認やプロセスの確認)を行うことができます。
$ pm2 monit
クラスタリングモードでの起動
最初に説明したpm2 start [スクリプトファイルパス]
ではforkモードという状態で起動しますが、起動モードにはクラスターモードというものも存在します。フォークモードでは起動したアプリ自体がリクエストを受け取りますが、クラスターモードではpm2のマスターノードがリクエストを受け取り、それを起動中のインスタンスに割り振ります(いわゆるロードバランシングをしてくれます)。この機能で、複数インスタンスを同時に立ち上げることで、マシンリソースを上限まで使うことができるようになります。具体的には、以下のように起動します。
# pm2 start [スクリプトファイル名] --name [名前] -i [起動数] # -i をつけると、クラスターモードになり、起動数=0にすると、マシンのコア数でインスタンスを起動してくれる. $ pm2 start app.js --name myapp -i 0 [PM2] Starting /Users/munesadayohei/git/node-playground/010-pm2/app.js in cluster_mode (0 instance) [PM2] Done. ┌──────────┬────┬─────────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │ ├──────────┼────┼─────────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤ │ myapp │ 0 │ cluster │ 43861 │ online │ 0 │ 0s │ 13% │ 26.5 MB │ disabled │ │ myapp │ 1 │ cluster │ 43862 │ online │ 0 │ 0s │ 30% │ 27.2 MB │ disabled │ │ myapp │ 2 │ cluster │ 43863 │ online │ 0 │ 0s │ 28% │ 26.8 MB │ disabled │ │ myapp │ 3 │ cluster │ 43864 │ online │ 0 │ 0s │ 25% │ 26.9 MB │ disabled │ └──────────┴────┴─────────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘今回のマシンの場合、4コアあるので、4つのクラスターが起動しています。クラスターモードで複数インスタンスを立ち上げておけば、
restart
などで再起動する場合にも、ダウンタイム0で再起動することができます。設定ファイルを用いた起動指定
起動オプションで便利な振る舞いを指定できますが、一度にたくさんを指定するのは面倒です。起動オプションは設定ファイル(YamlまたはJSON形式)で定義することもできます。その設定ファイルをstart
コマンドに渡すことで、便利なオプションを複数指定して起動することができます。Yaml形式の場合
# ファイル名:pm2config.yml(ファイル名は自由です) name: myapp # アプリ名 script: app.js # スクリプトファイルパス exec_mode: "cluster" # 起動モード = cluster instances: 0 # 起動インスタンス数 log-date-format: "YYYY-MM-DD HH:mm Z" # ログに日付を追加
JSONの場合
// ファイル名:pm2config.json(ファイル名は自由です) { "name": "myapp", "script": "app.js", "exec_mode": "cluster", "instances": 0, "log-date-format": "YYYY-MM-DD HH:mm Z" }基本的には、Yamlの方がシンプルだしコメントも書けるので、Yaml定義が良いなぁと思います。
上記の設定ファイルを用いて起動するには、以下のように行います。
# Yamlファイルを指定して、起動する場合 $ pm2 start pm2config.yml # JSONファイルを指定して、起動する場合 $ pm2 start pm2config.json
参考資料
今回は、以下の公式資料を利用しました。他にも色々とコマンドが紹介されているので、一読する価値は高いです。http://pm2.keymetrics.io/docs/usage/quick-start/
最後に
PM2は非常に便利で、他にも色々な使い方をしているので、その辺もブログにアウトプットしていきたいなと思います。最後になりますが本ブログでは、Linux・インフラ・開発環境・Python・フロントエンド・Go言語・Node.js・Swift・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSやTwitterをフォローして頂けると幸いです ^ ^。
最後までご覧頂きましてありがとうございました!