【サンプル付き】Nginx のリバースプロキシでキャッシュして高速化する

Webサイトの表示が遅いと、それだけページの離脱率が上昇してしまいます。
そのため、SEOの観点からもWebサイトの読み込み速度は重要です。

リバースプロキシでレスポンスをキャッシュすることで、
バックエンドサーバー(リバースプロキシの向き先として設定しているサーバー)で処理させることなく即座に応答することが可能になります。

したがって、多くのWebサイトで読み込み速度の改善が期待できます。

今回は、Nginxのリバースプロキシとして利用している場合において、
NginxでキャッシュさせることでWebサイトのパフォーマンスを改善させる方法を紹介します。

目次

構成図

リバースプロキシ設定

まずは、リバースプロキシの設定方法について。

以下の記事でも、Nginxをリバースプロキシとして利用して、WordPressの前にNginxを配置する方法を紹介しました。

設定例

server {
        listen 80;
        server_name example.com;

        location / {
                proxy_pass http://example/;
                proxy_redirect          off;

                # リクエストヘッダーの情報を下位のサービスに伝える
                proxy_set_header        Host            $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

                # タイムアウト設定
                proxy_connect_timeout   10;
                proxy_send_timeout      30;
                proxy_read_timeout      60;
        }
}

proxy_pass

バックエンドサーバーのURLを指定します。

proxy_set_header

NginxへのHTTPリクエストのリクエストヘッダー部に記載されているアクセス元の情報を、バックエンドサーバーに伝達するための設定です。
バックエンドサーバーのアクセスログ等に本当のアクセス元を記録するために設定します。

proxy_connect_timeout

Nginx がバックエンドへコネクションを張るときのタイムアウト時間です。
通常は、ローカルや同一ネットワークの場合はミリ秒単位でもでコネクションが張られるはずですが、
バックエンドのレイテンシーが極度に上昇している場合等、設定した時間でコネクションを張るのを諦めてくれます。
僕は、10秒に設定しています。

proxy_send_timeout

Nginx がバックエンドにデータを送信するときのタイムアウト時間です。
僕は、30秒に設定しています。

proxy_read_timeout

バックエンドが処理をして Nginx に応答を返却するときのタイムアウト時間です。
巨大な処理をバックエンドで行う場合は長めに設定してあげる必要があります。
僕は、60秒に設定しています。

キャッシュ設定

Nginxで静的コンテンツ等をキャッシュして、バックエンドで処理をすることなく応答するための設定です。

nginx.conf への設定例

http {
  include /etc/nginx/mime.types;
  default_type  application/octet-stream;

  proxy_cache_path              /var/cache/nginx/cache levels=1:2 keys_zone=zone1:64m inactive=7d max_size=2048m;
  proxy_temp_path               /var/cache/nginx/temp;

  include /etc/nginx/conf.d/*.conf;
}

proxy_cache_path

キャッシュファイルを保存するパスを指定します。
ディレクトリが存在しない場合は、自動的に作成されます。
僕は、/var/cache/nginx/cacheを指定しています。

levels

省略または 1 を指定した場合は path のディレクトリ直下にキャッシュファイルが並びます。
1:2 とした場合は、

$ tree
.
|-- 0
|   `-- 01
|       `-- 3bbb15b549cfec20071f292131a0d010
|-- 1
|   |-- 09
|   |   `-- 7062e2ce9e99aba4cb8ffb26e00f4091

のように、キャッシュファイルが並びます。
キャッシュ数が多い場合は階層が深い方が走査速度が速くなる気がします。

keys_zone=name:size

nameは、キーゾーン名です。proxy_cache_pathを複数定義することができ、locationディレクティブ毎にそれぞれ利用するキャッシュ設定のキーゾーン名を指定することができます。

sizeは、キーゾーンに割り当てるメモリサイズです。キャッシュするファイルそのものが使用するメモリではなく、キャッシュのキーを記憶しておくために利用されるという理解です。

In addition, all active keys and information about data are stored in a shared memory zone, whose name and size are configured by the keys_zone parameter. One megabyte zone can store about 8 thousand keys.

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_path

1MBあれば8000個のキャッシュキーを保存できるとあるので、小規模なら1MB、大規模でも数MBくらいあれば足りるケースが多いのではないでしょうか。
ただ、大量にメモリを消費するわけでもないので、メモリに余裕があるのであれば、10MBだったり30MBだったりを指定しても良いと思います。

inactive

キャッシュを保持しておく期間を設定します。この期間を過ぎるとキャッシュは削除されます。

max_size

キャッシュの最大サイズです。合計のキャッシュサイズが、ここで指定した容量以上になった場合に、最近使用していないキャッシュから自動的に削除されます。

proxy_temp_path

キャッシュファイルを作成する際に、proxy_cache_pathで指定したパスにキャッシュファイルが作成されるわけですが、
proxy_temp_pathを指定しておくと、proxy_temp_pathで指定したパスに一時ファイルとして書き出したのちに、proxy_cache_pathのパスに移動するようになります。

conf.d/*.conf への設定例

server {
        listen 80;
        server_name example.com;

        location / {
                proxy_pass http://example/;
                proxy_redirect          off;

                # リクエストヘッダーの情報を下位のサービスに伝える
                proxy_set_header        Host            $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

                # タイムアウト設定
                proxy_connect_timeout   10;
                proxy_send_timeout      30;
                proxy_read_timeout      60;

                # デフォルトではキャッシュしない
                set $no_not_cache 1;

                # 静的コンテンツのみキャッシュする
                if ($uri ~* "\.(jpg|jpeg|png|webp|gif|mp4|css|js|ico)$") {
                    set $do_not_cache 0;
                }

                proxy_no_cache          $do_not_cache;
                proxy_cache_bypass      $do_not_cache;

                proxy_cache             zone1;
                proxy_cache_key         $mobile$scheme$proxy_host$uri$is_args$args;
                proxy_cache_valid       200 201 6h;
                proxy_cache_valid       302 3h;
                proxy_cache_valid       301 1d;
                proxy_cache_valid       404 5m;
                proxy_cache_lock        on;
                proxy_buffering         on;
                proxy_ignore_headers    X-Accel-Redirect X-Accel-Expires Cache-Control Expires Vary;
                add_header              X-Cache-Status $upstream_cache_status;
        }
}

設定を適用する

nginx -tで設定に誤りが無いことを確認します。

$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

設定ファイルを読み込み直す。

CentOS 7 や Amazon Linux 2 での例:

$ sudo systemctl reload nginx

CentOS 6 や Amazon Linux での例)

$ sudo service nginx reload

この記事が気に入ったら
いいね または フォローしてね!

よかったらシェアしてね!
目次