Nginx のパフォーマンスについて

dev

Apache と Nginx

Apache の性質上 C10K 問題が発生してしまう。クライアント1万台問題というもので、同時接続するクライアントが多いとキャパシティを超えてしまうこと。例えばプロセス番号の割り当ては約3万。Apache は1リクエストに対して1プロセスを生成するので、プロセス番号が同時接続数の上限になる。サーバ自体のキャパシティに問題がなくても、ソフトウェア的な上限が決まっている。
Nginxは1プロセスで複数のリクエストを処理できる。プロセス内での同時接続数を設定可能で、全体のキャパシティは プロセス数xプロセス内での同時接続数になる。
シングルスレッドのNginxは動的コンテンツなどの重たい処理には向かない。同時処理数が増える時はシングルスレッドのほうが有利。メモリ使用量も増えない。マルチプロセスだとリクエストが増えるとメモリ消費量も増える。

ApacheとNginxを比較!それぞれのメリット・デメリットを解説

Nginx の設定項目

【Nginx】ちょっと時間を掛けてチューニングしてみた。 を参考に設定値について。

worker_processes

workerプロセスの数を指定。CPUコア数を超えないように設定する。autoにすると自動的に設定してくれる。

CPUコア数は nproc などで確認できる。

[Linux] CPU コア数を確認するコマンド

worker_connections

1つのworkerプロセスの同時接続数の上限。nginxをリバプロとして使う場合はクライアントからの接続とプロキシとしての接続の2接続になることに注意。

8コアで worker_connections を1024に設定すると8192接続まで可能になる。

worker_rlimit_nofile

workerプロセスが開くファイル数の上限。OSのファイルディスクリプタ数 / worker_processes を超えないように指定する。

ファイルディスクリプタ数は次のように確認できます。

OS全体で開けるファイル数。

cat /proc/sys/fs/file-max

1プロセスで同時に開けるファイル数。デフォルトでは1024

ulimit -n

Linuxのファイルディスクリプタ数を変更・確認する方法

同時接続数をオーバーしたとき

エラーログに次のように表示されます。

1024 worker_connections are not enough

このときは同時接続数が不足しているので、サーバのスペック的に許される範囲で worker_connections の値を大きくします。

stub_status

Nginx でも Apache の server-status のようにサーバの概況を見ることができます。conf ファイルに次のように追記して設定を反映します。

location /server-status {
  stub_status on; # これでstubが有効になる
	access_log off;
	allow 127.0.0.1;
	deny all;
}

http://example.com/server-status にアクセスすると次のような表示が得られます。

Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106

プロキシのハンドリング

プロキシ時の upstream の切り替えやタイムアウト設定項目は次のようになっています。下記はデフォルト値です。

proxy_next_upstream error timeout;
proxy_next_upstream_tries 0;
proxy_next_upstream_timeout 0;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

proxy_next_upstream* は upstream が利用不可能と判断されたときに、次のサーバにリクエストを送るための設定です。proxy_next_upstream はリクエスト失敗とする状況を指定します。次の項目で詳しく説明します。proxy_next_upstream_triesproxy_next_upstream_timeout はそれぞれ次のサーバに何回りクエストを送るか、次のサーバとのタイムアウト時間を指定します。デフォルトの 0 は無制限であることを意味します。

passive check

Nginx をプロキシサーバとして使っている場合、バックエンドサーバなどプロキシ先の upstream がエラーを起こす場合があります。

このとき、Nginx はエラーになっている upstream へのプロキシを一時的に停止して、有効な upstream へのみプロキシします。

もう少し詳しく言うと、proxy_next_upstream に設定したステータスを失敗とみなし、失敗になった数が max_fails で指定される上限に達するとその upstream が使えなくなります。

例えば proxy_next_upstream を次のように設定します。

location / {
  proxy_next_upstream error timeout http_502 http503;
  max_fails 1;
}

この設定では、エラー、タイムアウト、502、503になったとき失敗とカウントして、1回失敗になると次の upstream にプロキシします。

例えばタイムアウトが発生して、失敗が max_fails に達して upstream を切り替えるときには次のようなメッセージがエラーログに吐かれます。

upstream server temporarily disabled while reading response header from upstream
upstream timed out (110: Connection timed out) while reading response header from upstream

さらに、次の upstream も同じ状況になるなどして、すべての upstream を使い切ったときにアクセスすると、下記のようなログが出て 502 を返すようになります。

no live upstreams while connecting to upstream

Reference

タイトルとURLをコピーしました