NGINXは、コンテンツとアプリケーションの配信を高速化し、セキュリティを強化し、スケーラビリティを向上させる統合オープンソースの高性能Webサーバーです。Nginxの最も一般的な使用例の1つは、コンテンツキャッシュであり、これはウェブサイトのパフォーマンスを向上させる最も効果的な方法です。
関連記事: Linux向けのトップ10オープンソースキャッシングツール
NGINXを使用して、アップストリームサーバーからのレスポンスをキャッシュするように構成して、ローカルオリジンサーバーを高速化したり、コンテンツ配信ネットワーク(CDN)向けのエッジサーバーを作成したりできます。NGINXはいくつかの最大のCDNを支えています。
キャッシュとして構成された場合、NGINXは次のようになります:
- 静的および動的コンテンツをキャッシュします。
- マイクロキャッシングにより動的コンテンツのパフォーマンスを向上させます。
- パフォーマンスを向上させるためにバックグラウンドで再検証しながら古いコンテンツを提供します。
- Cache-Controlヘッダーをオーバーライドまたは設定し、その他の操作を行います。
この記事では、LinuxでNGINXをコンテンツキャッシュとして構成する方法を学び、ウェブサーバーをできるだけ効率的に実行します。
前提条件:
LinuxサーバーにNGINXがインストールされている必要があります。インストールされていない場合は、次のガイドに従ってNginxをインストールしてください:
Nginxで静的コンテンツをキャッシュする
静的コンテンツとは、ウェブサイトのコンテンツで、ページ間で変化しないものです。静的コンテンツの例には、画像、動画、ドキュメント、CSSファイル、JavaScriptファイルなどがあります。
ウェブサイトが多くの静的コンテンツを利用している場合、ブラウザが静的コンテンツのコピーを高速にアクセスするために保存するクライアントサイドキャッシュを有効にすることで、パフォーマンスを最適化できます。
次のサンプル構成は良い例です。単にwww.example.com
をウェブサイト名のURLに置き換え、他のパス名を適切に修正してください。
server { # substitute your web server's URL for www.example.com server_name www.example.com; root /var/www/example.com/htdocs; index index.php; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; location / { try_files $uri $uri/ /index.php?$args; } location ~ .php$ { try_files $uri =404; include fastcgi_params; # substitute the socket, or address and port, of your WordPress server fastcgi_pass unix:/var/run/php5-fpm.sock; #fastcgi_pass 127.0.0.1:9000; } location ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg |jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid |midi|wav|bmp|rtf)$ { expires max; log_not_found off; access_log off; } }
Nginxで動的コンテンツをキャッシュする
Nginxは、ローカルファイルシステムのどこかにある永続的なディスクベースのキャッシュを使用します。まず、キャッシュされたコンテンツを保存するためのローカルディスクディレクトリを作成してください。
# mkdir -p /var/cache/nginx
次に、キャッシュディレクトリに適切な所有権を設定します。キャッシュディレクトリは、次のようにNginxユーザー(nginx)とグループ(nginx)によって所有される必要があります。
# chown nginx:nginx /var/cache/nginx
次に、以下のセクションでNginxで動的コンテンツを有効にする方法を見ていきます。
NGINXでFastCGIキャッシュを有効にする
FastCGI(またはFCGI)は、PHPなどのインタラクティブアプリケーションをNGINXなどのWebサーバーと連携させるための広く使用されているプロトコルです。これはCGI(Common Gateway Interface)の拡張機能です。
FCGIの主な利点は、複数のCGIリクエストを1つのプロセスで管理できることです。これがないと、Webサーバーはサービスのためにクライアントリクエストごとに新しいプロセスを開く必要があります(それを制御し、リクエストを処理し、閉じる必要があります)。
PHPスクリプトをLEMPスタックデプロイメントで処理するには、NGINXがFPM(FastCGI Process Manager)またはPHP-FPMを使用します。人気のある代替PHP FastCGI実装です。一度PHP-FPMプロセスが実行されると、NGINXは処理のためにそれに対してリクエストをプロキシするように構成されます。したがって、NGINXはPHP-FPMバックエンドアプリケーションサーバーからの応答をキャッシュするようにも構成できます。
NGINXでは、FastCGIコンテンツキャッシュは、NGINX構成構造内のトップレベルのhttp{}
コンテキストでfastcgi_cache_path
というディレクティブを使用して宣言されます。また、キャッシュ用のキー(リクエスト識別子)を定義するfastcgi_cache_key
を追加することもできます。
http {}
コンテキスト内にadd_header X-Cache-Statusディレクティブを追加して、上流キャッシュの状態を読み取ります-これはデバッグ目的で便利です。
サイトのサーバーブロック構成ファイルが/etc/nginx/conf.d/testapp.confまたは/etc/nginx/sites-available/testapp.confにあると仮定します(Ubuntuおよびその派生版の場合)、編集用のファイルを開き、ファイルの先頭に次の行を追加します。
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHEZONE:10m; inactive=60m max_size=40m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; add_header X-Cache $upstream_cache_status;

fastcgi_cache_path
ディレクティブは次のパラメータの数を指定します:
- /var/cache/nginx – キャッシュのためのローカルディスクディレクトリへのパス。
- levels – キャッシュの階層レベルを定義し、/var/cache/nginxの下に2レベルのディレクトリ階層を設定します。
- keys_zone (name:size) – 全てのアクティブなキーとデータ(メタ情報)の情報を保存する共有メモリゾーンの作成を有効にします。キーをメモリに保存することで、NGINXがディスク上のステータスを確認する必要なく、MISSまたはHITかどうかを容易に判断できるようになります。
- inactive – 指定された時間内にアクセスされないキャッシュされたデータが、新鮮さに関係なくキャッシュから削除されるまでの時間を指定します。例の構成では、60mの値は、60分間アクセスされなかったファイルがキャッシュから削除されることを意味します。
- max_size – キャッシュの最大サイズを指定します。ここで使用できる他のパラメータがあります(詳細はNGINXのドキュメントを参照してください)。
fastcgi_cache_key
ディレクティブの変数は以下のように記述されています。
NGINXはこれらを使用してリクエストのキー(識別子)を計算します。重要なのは、キャッシュされたレスポンスをクライアントに送信するためには、リクエストがキャッシュされたレスポンスと同じキーを持っている必要があるということです。
- $scheme – リクエストのスキーム、HTTPまたはHTTPS。
- $request_method – リクエストメソッド、通常は「GET」または「POST」。
- $host – これはリクエスト行からのホスト名、または「Host」リクエストヘッダーフィールドからのホスト名、またはリクエストに一致するサーバー名です。優先順位の順に。
- $request_uri – 全原本のリクエストURI(引数付き)を意味します。
また、$upstream_cache_status
変数は、NGINXが応答する各リクエストに対して計算されます。それがMISS(キャッシュ内に見つからない応答、アプリケーションサーバーから取得)であるか、HIT(キャッシュから提供される応答)であるか、またはその他のサポートされている値のいずれかであるか。
次に、PHPリクエストをPHP-FPMに渡すlocation
ディレクティブ内で、先ほど定義したキャッシュを有効にするためにfastcgi_cache
ディレクティブを使用します。
また、異なる応答に対してキャッシュ時間を設定するために、fastcgi_cache_valid
ディレクティブを使用します。
fastcgi_cache CACHEZONE; fastcgi_cache_valid 60m;

キャッシュ時間のみが指定されている場合、200、301、および302のレスポンスがキャッシュされます。ただし、レスポンスを明示的に指定するか、任意の(すべてのレスポンスコードに対して)使用することもできます:
fastcgi_cache CACHEZONE; fastcgi_cache_valid 200 301 203 60m; fastcgi_cache_valid 404 10m; OR fastcgi_cache CACHEZONE; fastcgi_cache_valid any 10m;
NginxでFastCGIキャッシュのパフォーマンスを微調整する
同じキーを持つリクエストがキャッシュされる前に行われる必要がある最小回数を設定するには、fastcgi_cache_min_uses
ディレクティブをhttp{}
、server{}
、またはlocation{}
コンテキストに含めます。
fastcgi_cache_min_uses 3

期限切れのキャッシュアイテムの再検証を条件付きリクエストを使用して有効にするには、「If-Modified-Since」および「If-None-Match」ヘッダーフィールドを使用し、fastcgi_cache_revalidate
ディレクティブをhttp{}
、server{}
、またはlocation{}
コンテキスト内に追加します。
fastcgi_cache_revalidate on;

NGINXに、オリジンサーバーまたはFCGIサーバーがダウンしている場合にキャッシュされたコンテンツを提供するよう指示するには、proxy_cache_use_stale
ディレクティブを、locationディレクティブ内に含めます。
このサンプル構成では、NGINXがエラー、タイムアウト、およびアップストリームサーバーから指定されたエラーのいずれかを受信し、キャッシュされたコンテンツに要求されたファイルの古いバージョンがある場合、古いファイルを提供します。
proxy_cache_use_stale error timeout http_500;

別の有用な指令で FCGI キャッシュのパフォーマンスを調整する方法は、fastcgi_cache_background_update
ディレクティブを使うことです。これは、proxy_cache_use_stale
ディレクティブと連動して動作します。このディレクティブを「on」に設定すると、NGINX に対し、クライアントが期限切れまたはアップストリームサーバから更新中のファイルを要求した場合に、古いコンテンツを提供するよう指示します。
fastcgi_cache_background_update on;

fastcgi_cache_lock
も便利です。キャッシュのパフォーマンスを調整する際に、キャッシュに存在しないコンテンツを複数のクライアントが要求した場合、NGINX は最初のリクエストのみをアップストリームサーバに転送し、応答をキャッシュしてから他のクライアントの要求をキャッシュから提供します。
fastcgi_cache_lock on;

上記のすべての変更を NGINX 設定ファイルに適用したら、保存して閉じます。その後、NGINX サービスを再起動する前に、構成構造に構文エラーがないか確認します。
# nginx -t # systemctl restart nginx

次に、キャッシュが正しく機能しているかテストします。次の curl コマンド を使用して、ウェブアプリケーションまたはサイトにアクセスしようとします(初回は MISS を示し、その後のリクエストはスクリーンショットに示すように HIT を示すはずです)。
# curl -I http://testapp.tecmint.com

以下は、NGINX が古いデータを提供しているスクリーンショットです。

キャッシュをバイパスする例外を追加します。
NGINXは、fastcgi_cache_bypass
ディレクティブを使用して、キャッシュされたレスポンスをクライアントに送信しない条件を設定することが可能です。また、アップストリームサーバーからのレスポンスを全くキャッシュしないようにNGINXに指示するには、fastcgi_no_cache
を使用します。
たとえば、POSTリクエストとクエリ文字列を持つURLが常にPHPに送られるようにしたい場合、まず、次のように条件を設定するif文を宣言します。
set $skip_cache 0; if ($request_method = POST) { set $skip_cache 1; }
次に、PHPリクエストをPHP-FPMに渡すlocation
ディレクティブで、上記の例外をアクティブにします。これには、fastcgi_cache_bypass
およびfastcgi_no_cache
ディレクティブを使用します。
fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache;
コンテンツキャッシュを有効にしたくないサイトの他の部分も多数あります。以下は、WordPressサイトのパフォーマンスを向上させるためのNGINX構成の例です。これは、nginx.comのブログで提供されています。
これを使用するには、環境に存在するものを反映するように変更します(ドメイン、パス、ファイル名など)。
fastcgi_cache_path /var/run/NGINX-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; server { server_name example.com www.example.com; root /var/www/example.com; index index.php; access_log /var/log/NGINX/example.com.access.log; error_log /var/log/NGINX/example.com.error.log; set $skip_cache 0; # POST requests and URLs with a query string should always go to PHP if ($request_method = POST) { set $skip_cache 1; } if ($query_string != "") { set $skip_cache 1; } # Don't cache URIs containing the following segments if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php |sitemap(_index)?.xml") { set $skip_cache 1; } # Don't use the cache for logged-in users or recent commenters if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass |wordpress_no_cache|wordpress_logged_in") { set $skip_cache 1; } location / { try_files $uri $uri/ /index.php?$args; } location ~ .php$ { try_files $uri /index.php; include fastcgi_params; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache WORDPRESS; fastcgi_cache_valid 60m; } location ~ /purge(/.*) { fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1"; } location ~* ^.+.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg |gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi |wav|bmp|rtf)$ { access_log off; log_not_found off; expires max; } location = /robots.txt { access_log off; log_not_found off; } location ~ /. { deny all; access_log off; log_not_found off; } }
NGINXでプロキシキャッシュを有効にする
NGINXはまた、他のプロキシされたサーバーのレスポンスをキャッシュする機能もサポートしています(proxy_pass
ディレクティブで定義されます)。このテストケースでは、NGINXをNode.jsウェブアプリケーションのリバースプロキシとして使用しているため、NGINXをNode.jsアプリケーションのキャッシュとして有効にします。ここで使用されるすべての構成ディレクティブは、前のセクションのFastCGIディレクティブと同様の意味を持っているため、再度説明しません。
プロキシサーバーからのレスポンスのキャッシュを有効にするには、トップレベルのhttp{}
コンテキストにproxy_cache_path
ディレクティブを含めます。リクエストがキャッシュされる方法を指定するには、次のようにproxy_cache_key
ディレクティブを追加することもできます。
proxy_cache_path /var/cache/nginx app1 keys_zone=PROXYCACHE:100m inactive=60m max_size=500m; proxy_cache_key "$scheme$request_method$host$request_uri"; add_header X-Cache-Status $upstream_cache_status; proxy_cache_min_uses 3;
次に、場所ディレクティブでキャッシュをアクティブにします。
location / { proxy_pass http://127.0.0.1:3000; proxy_cache PROXYCACHE; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; }
NGINXがキャッシュされたコンテンツを送信せず、アップストリームサーバーからのレスポンスをまったくキャッシュしない条件を定義するには、proxy_cache_bypass
およびproxy_no_cache
を含めます。
proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment; proxy_no_cache $http_pragma $http_authorization;
プロキシキャッシュのパフォーマンスを微調整する
次のディレクティブは、プロキシキャッシュのパフォーマンスを微調整するのに役立ちます。これらは、FastCGIディレクティブと同じ意味も持っています。
proxy_cache_min_uses 3; proxy_cache_revalidate on; proxy_cache_use_stale error timeout updating http_500; proxy_cache_background_update on; proxy_cache_lock on;
詳細な情報やキャッシングの構成ディレクティブについては、ngx_http_fastcgi_moduleおよびngx_http_proxy_moduleの2つの主要なモジュールのドキュメントを参照してください。
追加リソース:NGINXコンテンツキャッシングおよびWordPressパフォーマンスの改善に関するヒント。