【Nginx】ちょっと時間を掛けてチューニングしてみた。

nginx-tuningNginx

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_processesworkerプロセスの数を指定する。CPUコア数を超えないように設定することが大事。「auto」にすることで自動的に設定してくれる。auto
worker_connections1workerプロセスの同時接続数の最大値。リバースプロキシとして利用する場合、1接続あたり、クライアントからの接続とプロキシとしての接続の2接続を考える必要がある。以下の式で考えるとよいかと。
worker_rlimit_nofile / 2(接続)× 2(安全率)
2048
worker_rlimit_nofileworkerプロセスが開くファイル数の上限。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_conn1つのIPアドレスからの接続数の制限値を設定する。右記の設定の場合、addrというゾーン名で定義されたメモリ領域を使用し、1つのIPアドレスから100接続許可するという意味になる。サイトによって、1ページあたりのリクエスト数とかが変わってくるので調整が必要。100
gzipレスポンスをgzipで圧縮する。on
gzip_http_version圧縮する最小のHTTPバージョン。今回はバージョン1.0〜から圧縮するように設定。1.0
gzip_comp_levelgzipの圧縮レベル。1〜9まであるが、1と9では圧縮率はそれほど変わらないため、圧縮時間がより短い1を設定。1
gzip_types指定されたMIMEタイプを圧縮対象とする。「*」は全てという意味だが、デメリットが見つからないためこれを設定。*
open_file_cacheファイルディスクリプタやサイズをキャッシュして、ファイルのOpenやCloseのシステムコールの負荷を減らす役割。max=1000 inactive=10s;
open_file_cache_validopen_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の設定を変更するだけでパフォーマンスが上がるのでお試しあれ!

コメント

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