nginxのworker_processes、worker_rlimit_nofile、worker_connectionsディレクティブの挙動を確認する

nginxの設定を行う必要があり、worker_processes、worker_rlimit_nofile、worker_connectionsディレクティブ当たりについて調べてみたのでメモ

# 環境

+ Amazon Linux AMI 2015.09 
+ スペックはt2.micro
+ nginx1.8.0

# 参考

+ [Nginxポケットリファレンス](http://gihyo.jp/book/2015/978-4-7741-7633-8)
+ [nginx で Too many open files エラーに対処する](http://www.1x1.jp/blog/2013/02/nginx_too_many_open_files_error.html)

# 結論

+ 同時クライアント数はworker_process * worker_connectionとなる
+ worker_processesディレクティブではnginxのワーカープロセス数を指定する。CPUのコア数を設定するのが推奨。autoとしておけばコア数を見て自動設定するようなのでこの設定をしておくのが良さそう
+ worker_rlimit_nofileディレクティブを設定すればnginxのワーカープロセスのディスクプリンタを設定する事ができる。nginxで「Too many open files」などと表示された場合やworker_connectionsの値を上げる場合にこの設定を行う。
+ worker_connectionsディレクティブではワーカープロセスで許容するコネクション数を指定する。この値はディスクプリンタ以上の設定ができないので、設定を上げる場合にはworker_rlimit_nofileを設定したほうが良い

# worker_processes

autoにすれば自動でコア数を設定してくれるようですが、念のため確認。

[nginx の worker_processes を auto にしたときの挙動](http://ponde.hatenadiary.com/entry/2014/05/23/225320)


lscpuコマンドの  **CPU(s)** の項でコア数を確認できる。

```bash
$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                1
On-line CPU(s) list:   0
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 62
Model name:            Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz
Stepping:              4
CPU MHz:               2494.052
BogoMIPS:              4988.10
Hypervisor vendor:     Xen
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              25600K
NUMA node0 CPU(s):     0
```

nginxの設定ファイルで `worker_processes  auto;` となっているのを確認し、確認後、起動。

プロセスを確認してみます。

```bash
$ ps aux |grep nginx |grep -v grep
root     22994  0.0  0.1 109192  1960 ?        Ss   05:35   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    22996  0.0  0.6 109628  6888 ?        S    05:35   0:00 nginx: worker process
```

コア数が1なので、workerプロセスは１つのみ起動しているのを確認。（上の方はmasterプロセス）

# worker_rlimit_nofileとworker_connections

worker_rlimit_nofileディレクティブではディスクリプリンタの値の設定が出来ます。ディスクプリンタについては以下が参考になりました。

+ [ファイルディスクリプタについて](http://inokara.hateblo.jp/entry/2013/09/28/051108)
+ [【Linux】ファイルディスクリプタとは何か【stream】](http://www.fisproject.jp/2013/11/%E3%80%90linux%E3%80%91%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%BF%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B%E3%80%90stream%E3%80%91/)

nginxではworker_connectionsディレクティブで指定できる値はディスクプリンタの値以上を設定することが出来ないので、必要に応じて変更する必要があります。

> It should be kept in mind that this number includes all connections (e.g. connections with proxied servers, among others), not only connections with clients. Another consideration is that the actual number of simultaneous connections cannot exceed the current limit on the maximum number of open files, which can be changed by worker_rlimit_nofile.

特に何も設定しない状態のディスクプリンタは以下で確認できます。

```bash
$ ulimit -n
1024
```

上記よりworker_connectionsディレクティブで1024以上を指定する場合には少なくとも設定が必要です。

変更する場合ですが、まずはOS全体でどれだけのファイルディスクリプタについて設定できるか確認します。

```bash
$ cat /proc/sys/fs/file-max
100015
```

AmazonLinuxデフォルトではOS全体で100015のファイルが扱えるようです。

とりあえず今回の例では倍の2048の値を設定するようにしたいと思います。

まず、特に何も設定しない状態で確認します。

```bash
# workerのプロセスIDを確認
$ps aux |grep nginx |grep -v grep
root     23064  0.0  0.1 109192  1964 ?        Ss   06:15   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    23066  0.0  0.6 109628  6660 ?        S    06:15   0:00 nginx: worker process

# workerでのファイルディスクリプタを確認
$cat /proc/23066/limits |grep open
Max open files            1024                 4096                 files
```

３列目の値はHardLimitとなっており、rootのみ変えれる値で、現在の設定値は２列目の1024となっているのが確認できます。

では、worker_rlimit_nofileディレクティブを設定してnginxのサービスを再起動します。

```lang:/etc/nginx.conf
worker_rlimit_nofile  2048;
```

```bash
$sudo service nginx restart
$cat /proc/23095/limits |grep open
Max open files            2048                 2048                 files
```

設定によってworkerプロセスのファイルディスクリプタの設定が変わっているのが確認できました。
また、特に設定しない場合、HardLimitは4096となっていましたが、これ以上の設定をworker_rlimit_nofileディレクティブで行っても設定が反映されていました。

ファイルディスクリプタの変更ができることが確認できたので、併せてworker_connectionsも増やすことが出来そうです。