PM2のinstancesの値の変更時の確認方法

あけましておめでとうございます。
この記事を編集していたら年を越していました。

## EC2のインスタンスを作成

| key | value  |
|---|---|
|インスタンスタイプ  |t2.micro  |
|vCPU |1  |

## Node.js, pm2をインストール

```
curl -sL https://rpm.nodesource.com/setup_12.x | bash -
yum install nodejs -y
node -v
> v12.20.0
npm -v
> 6.14.8
npm install pm2 -g
> 4.5.1
```

[distributions/README.md at master · nodesource/distributions · GitHub](https://github.com/nodesource/distributions/blob/master/README.md#installation-instructions-1)

## PM2の設定

```
# 再帰的にディレクトリを作成する
mkdir -p /var/www/test
# pm2の設定ファイルを作成
touch pm2.yaml
# pm2の設定ファイルを編集
vi pm2.yaml
```

``` pm2.yaml
apps:
  - script   : ./app.js
    name     : 'tes-app'
    instances: -1 # cpuの数-1のプロセスを起動。（clusterモードに限る）
    # instances: 0 # cpuの数に応じて最大のプロセスを起動。（clusterモードに限る）
    exec_mode: cluster # n個のインスタンスを起動し、クラスターモジュールに負荷分散を処理させます。
```

[PM2 - Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/)

コア数、環境もによりますが、`instances: -1`がよさそうです。（コア数8なら7プロセス起動）（脳死でMaxはNG）
また`t2.micro`は1コアのはずですが、`instances: 4`にするとプロセスが4つ起動しました。（どういう状態？）

参考: [Optimising NginX, Node.JS and networking for heavy workloads - GoSquared Blog](https://www.gosquared.com/blog/optimising-nginx-node-js-and-networking-for-heavy-workloads)

## Expressの準備

```
# expressをインストール（4.17.1: 2020/12/30）
npm install express
```

[Node.js アプリケーションの簡単なプロファイリング \| Node.js](https://nodejs.org/ja/docs/guides/simple-profiling/) のコードを今回はお借りします。

``` app.js
const express = require("express");
const crypto = require("crypto");
const app = express();

server = app.listen(3000, function(){
    console.log("Node.js is listening to PORT:" + server.address().port);
});

const users = [];

app.get('/newUser', (req, res) => {
    let username = req.query.username || '';
    const password = req.query.password || '';

    username = username.replace(/[!@#$%^&*]/g, '');

    if (!username || !password || users.username) {
        return res.sendStatus(400);
    }

    const salt = crypto.randomBytes(128).toString('base64');
    const hash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512');

    users[username] = { salt, hash };

    res.sendStatus(200);
});

app.get('/auth', (req, res) => {
    let username = req.query.username || '';
    const password = req.query.password || '';

    username = username.replace(/[!@#$%^&*]/g, '');

    if (!username || !password || !users[username]) {
        return res.sendStatus(400);
    }

    const { salt, hash } = users[username];
    const encryptHash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512');

    if (crypto.timingSafeEqual(hash, encryptHash)) {
        res.sendStatus(200);
    } else {
        res.sendStatus(401);
    }
});
```

## pm2を起動

```
pm2 start pm2.yaml 
[PM2][WARN] Applications test-app not running, starting...
[PM2] App [test-app] launched (1 instances)
┌─────┬─────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id  │ name        │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├─────┼─────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0   │ test-app    │ default     │ 1.0.0   │ cluster │ 24606    │ 0s     │ 0    │ online    │ 0%       │ 30.1mb   │ root     │ disabled │
└─────┴─────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
```

設定を変更したい場合は一度レジストリを削除してから再度スタートします。（restartだと変更した設定は反映されない）

```
pm2 delete test-app
pm2 start pm2.yaml 
```

以上。