Webサーバやリバースプロキシとしてよく使われるNginx。今回は、チューニングに焦点をあて、解説しました。アプリの修正をしなくとも、パフォーマンスが改善できるので是非ご参考あれ。
(自分の備忘も兼ねてたりします。)
※本ページはプロモーションが含まれています。
設定の紹介
チューニングした/etc/nginx/nginx.conf
がこちら。/etc/nginx/conf.d/default.conf
を別で読み込んで、デフォルトページを表示するようになっています。
user nginx;
worker_processes auto;
worker_rlimit_nofile 100000;
events {
worker_connections 2048;
multi_accept on;
use epoll;
}
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
http {
include /etc/nginx/mime.types;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay off;
keepalive_timeout 3;
client_header_timeout 60;
client_body_timeout 60;
reset_timedout_connection on;
send_timeout 60;
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 100;
default_type text/html;
charset UTF-8;
gzip on;
gzip_http_version 1.0;
gzip_disable "msie6";
gzip_proxied any;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript application/json;
open_file_cache max=1000 inactive=10s;
open_file_cache_valid 60s;
open_file_cache_min_uses 1;
open_file_cache_errors on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$request_time"';
access_log /var/log/nginx/access.log main;
include /etc/nginx/conf.d/*.conf;
}
ではでは、解説。
設定項目 | 解説 | 設定値 |
---|---|---|
worker_processes | workerプロセスの数を指定する。CPUコア数を超えないように設定することが大事。「auto」にすることで自動的に設定してくれる。 | auto |
worker_connections | 1workerプロセスの同時接続数の最大値。リバースプロキシとして利用する場合、1接続あたり、クライアントからの接続とプロキシとしての接続の2接続を考える必要がある。以下の式で考えるとよいかと。 worker_rlimit_nofile / 2(接続)× 2(安全率) | 2048 |
worker_rlimit_nofile | workerプロセスが開くファイル数の上限。Nginxをリバプロとして使用する場合は、1つの接続で、リクエストの受付とupstreamへのリクエストの2つのファイルを使用する。 「OSのファイルディスクリプタ / work_processes 」よりも小さい値を設定する! | 100000 |
multi_accept | 同時に複数のアクセスを受け入れることができる。迷うこと無くon。 | on |
server_tokens | セキュリティの観点からバージョンは表示させたくないのでoff。 | off |
tcp_nopush | 有効にすると、レスポンスヘッダとファイルの内容をまとめて送ることができるので、パケット数を減らすことができる! | on |
tcp_nodelay | 有効すると(KeepAlive状態のときのみ有効)送信済みデータの応答待ちの状態でも遅延させることなくデータ送信できるようなる。ユーザーレスポンスが良くなる場合もあるが、ネットワーク負荷が高くなる。今回は負荷を考えてoff。 | off |
keepalive_timeout | キープアライブのタイムアウト。同一クライアントからのコネクションを残しておいて、再接続の効率を上げる。長時間に設定すると通信が遅いクライアントがいる場合に接続が残り続けてしまうため、短い秒数を設定する。 | 3 |
client_header_timeout | クライアントのヘッダーを読み取る時間。LBよりも長い値に設定する必要がある。短くする根拠が不明だったため、デフォルトを設定。 | 60 |
client_body_timeout | クライアントのボディーを読み取る時間。LBよりも長い値に設定する必要がある。短くする根拠が不明だったため、デフォルトを設定。 | 60 |
reset_timedout_connection | タイムアウトした接続をリセットするかどうかの設定。有効にすると、リセットを行いメモリの圧迫を防ぐことができる。 | on |
send_timeout | クライアントに応答を返すまでのタイムアウト。明確な根拠がないためデフォルト値。 | 60 |
limit_conn_zone | 同時接続数制限の処理で確保するメモリサイズ。右記の設定の場合、addrというキーで10MBのメモリを確保する。 1MBで、約32,000の32バイト状態または約16,000の64バイト状態のIPアドレスを保持できる。 | $binary_remote_addr zone=addr:10m; |
limit_conn | 1つのIPアドレスからの接続数の制限値を設定する。右記の設定の場合、addrというゾーン名で定義されたメモリ領域を使用し、1つのIPアドレスから100接続許可するという意味になる。サイトによって、1ページあたりのリクエスト数とかが変わってくるので調整が必要。 | 100 |
gzip | レスポンスをgzipで圧縮する。 | on |
gzip_http_version | 圧縮する最小のHTTPバージョン。今回はバージョン1.0〜から圧縮するように設定。 | 1.0 |
gzip_comp_level | gzipの圧縮レベル。1〜9まであるが、1と9では圧縮率はそれほど変わらないため、圧縮時間がより短い1を設定。 | 1 |
gzip_types | 指定されたMIMEタイプを圧縮対象とする。「*」は全てという意味だが、デメリットが見つからないためこれを設定。 | * |
open_file_cache | ファイルディスクリプタやサイズをキャッシュして、ファイルのOpenやCloseのシステムコールの負荷を減らす役割。 | max=1000 inactive=10s; |
open_file_cache_valid | open_file_cacheの検知間隔。(キャッシュするかしないかをチェックする間隔。) | 60 |
open_file_cache_min_uses | 設定された回数使われていなければ、キャッシュされない。デフォルトで十分かと。 | 1s |
log_format combined | ログフォーマット。レスポンスタイプ「$request_time」を追加。 | ‘$remote_addr – $remote_user [$time_local] “$request” ‘ ‘$status $body_bytes_sent “$http_referer” ‘ ‘”$http_user_agent” “$http_x_forwarded_for” “$request_time”‘; |
どのくらい性能が上がった?
チューニング前
/ # wrk -c 100 -t 10 -d 10 --latency http://127.0.0.1
Running 10s test @ http://127.0.0.1
10 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 8.25ms 4.59ms 70.37ms 80.42%
Req/Sec 1.26k 490.97 8.05k 76.12%
Latency Distribution
50% 6.33ms
75% 10.95ms
90% 13.24ms
99% 26.30ms
125318 requests in 10.10s, 101.58MB read
Requests/sec: 12408.57
Transfer/sec: 10.06MB
/ #
チューニング実施後
/ # wrk -c 100 -t 10 -d 10 --latency http://127.0.0.1
Running 10s test @ http://127.0.0.1
10 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 6.96ms 2.54ms 32.25ms 77.99%
Req/Sec 1.45k 307.79 5.76k 85.63%
Latency Distribution
50% 6.54ms
75% 7.99ms
90% 9.93ms
99% 15.69ms
145062 requests in 10.09s, 118.69MB read
Requests/sec: 14377.90
Transfer/sec: 11.76MB
/ #
1秒間のリクエスト数が「12408」→「14377」増加。
90パーセンタイル(※)レイテンシーが「13.24ms」→「9.93ms」低下。
※アクセスした全体の90%の人のレイテンシー。
チューニングした結果、リクエスト数もレイテンシーも改善!!(正直、もっとリクエストも増えるかなーと思っていました。もう少しチューニングできる気がする。)
アプリを変更せずともNginxの設定を変更するだけでパフォーマンスが上がるのでお試しあれ!
コメント