Nginxをキャッシングリバースプロキシとして構成しようとしています。 OriginサーバーはApacheであり、重要な場合はWordPressインスタンスをホストします。
リバースプロキシ機能は期待どおりに機能していますが、キャッシュが機能していないようです。同じ静的リソースを2回続けて取得すると、x-proxy-cache: MISS
が2回取得されます。
assodigitale.itはドメイン、138.201.87.123はオリジンサーバーのIPアドレス、138.201.87.124はNginxプロキシのIPアドレスです。
オリジンサーバーは、プロキシがリソースをキャッシュできるように応答しているようです。
$ curl --connect-to ::138.201.87.123:443 --http2 -I https://assodigitale.it/wp-content/uploads/2018/03/aereo.jpg
HTTP/2 200
date: Sun, 11 Mar 2018 20:59:39 GMT
server: Apache/2.4.25 (Debian)
content-length: 32989
strict-transport-security: max-age=31536000; includeSubdomains; preload
last-modified: Wed, 07 Mar 2018 09:34:41 GMT
etag: "80dd-566cf44ca2952"
accept-ranges: bytes
vary: Accept-Encoding
cache-control: max-age=1209600, public
x-content-type-options: nosniff
content-type: image/jpeg
プロキシサーバーへの最初の要求は、予想どおり、MISSになります。
$ curl --connect-to ::138.201.87.124:443 --http2 -I https://assodigitale.it/wp-content/uploads/2018/03/aereo.jpg
HTTP/2 200
server: nginx/1.13.9
date: Sun, 11 Mar 2018 21:04:00 GMT
content-type: image/jpeg
content-length: 32989
strict-transport-security: max-age=31536000; includeSubdomains; preload
last-modified: Wed, 07 Mar 2018 09:34:41 GMT
etag: "80dd-566cf44ca2952"
vary: Accept-Encoding
cache-control: max-age=1209600, public
x-content-type-options: nosniff
x-proxy-cache: MISS
strict-transport-security: max-age=4838400; includeSubDomains; preload
accept-ranges: bytes
Nginxプロキシへの2番目のリクエストはHITになりますが、別のMISSになります。
$ curl --connect-to ::138.201.87.124:443 --http2 -I https://assodigitale.it/wp-content/uploads/2018/03/aereo.jpg
HTTP/2 200
server: nginx/1.13.9
date: Sun, 11 Mar 2018 21:05:52 GMT
content-type: image/jpeg
content-length: 32989
strict-transport-security: max-age=31536000; includeSubdomains; preload
last-modified: Wed, 07 Mar 2018 09:34:41 GMT
etag: "80dd-566cf44ca2952"
vary: Accept-Encoding
cache-control: max-age=1209600, public
x-content-type-options: nosniff
x-proxy-cache: MISS
strict-transport-security: max-age=4838400; includeSubDomains; preload
accept-ranges: bytes
これが私のnginx設定の関連部分です:
proxy_cache_path /srv/cache/nginx levels=1:2 keys_zone=revproxy:2000m inactive=2880m use_temp_path=off;
proxy_cache_key "$scheme$request_method$Host$request_uri";
proxy_cache_methods GET HEAD;
proxy_cache_valid any 1m;
proxy_cache_valid 200 1440m;
server {
listen 443 ssl http2;
ssl on;
server_name assodigitale.it;
ssl_certificate /etc/letsencrypt/live/assodigitale.it/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/assodigitale.it/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
location / {
proxy_cache revproxy;
add_header X-Proxy-Cache $upstream_cache_status;
add_header Strict-Transport-Security "max-age=4838400; includeSubDomains; preload";
proxy_pass https://138.201.87.123;
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
proxy_cache_bypass $http_x_forceflushcacheurl;
proxy_cache_lock on;
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_hide_header Upgrade;
proxy_buffering off;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
proxy_ignore_headers Set-Cookie;
http2_Push_preload on;
client_max_body_size 64M;
}
}
/srv/cache/nginx
ディレクトリには755の権限とwww-data
所有者があり、Nginxはwww-data
として実行されます。実際、Nginxはそこにフォルダー、つまり0 1 2 3 4 5 6 7 8 9 a b c d e f
を書き込みますが、非常に大規模でカジュアルなトラフィックをはるかに超えるサイトの場合、全体のスペースは344Kbになります。
上記と同じcurl
コマンドを試してみますが、画像の代わりにページを使用すると、まったく同じ結果が得られ、常にMISSになります。
Nginxがリソースのキャッシュを拒否するのはなぜですか?
proxy_buffering on
を設定する必要があります。そうしないと、nginxは応答をキャッシュしません!
公式 ドキュメント 言った:
バッファリングが無効になっている場合、応答は受信されるとすぐに同期的にクライアントに渡されます。 nginx will not try to read the whole response from the proxied server.
nginxがサーバーから一度に受信できるデータの最大サイズは、proxy_buffer_sizeディレクティブによって設定されます。
同様の問題がありました。 s3バケットのプロキシキャッシュとしてnginxを使用していました(IPホワイトリストをサポートできるようにするため)。プロキシがhttpsでサービスを提供していても、httpsエンドポイントからソーシングしていないことに気付きました。 nginxはそれが気に入らなかったようです。 http
からhttps
に切り替えたら、問題はありません。
実行している別の同様のNginxプロキシから構成をコピーし、Webサイトに適合させたところ、機能するようになりました。
これは私が現在使用している構成です:
proxy_cache_path /srv/cache/nginx levels=1:2 keys_zone=revproxy:2000m inactive=2880m use_temp_path=off;
proxy_cache_key "$scheme$request_method$Host$request_uri";
proxy_cache_methods GET HEAD;
proxy_cache_valid any 1m;
proxy_cache_valid 200 1440m;
server {
listen 443 ssl http2;
ssl on;
server_name assodigitale.it;
ssl_certificate /etc/letsencrypt/live/assodigitale.it/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/assodigitale.it/privkey.pem;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
keepalive_timeout 60;
ssl_session_timeout 10m;
location / {
proxy_cache revproxy;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_pass https://138.201.87.123;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
proxy_cache_lock on;
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_hide_header Upgrade;
proxy_buffering on;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
client_max_body_size 64M;
}
}
これは問題を解決するので答えになる可能性がありますが、なぜそれが機能するのか(より正確には、以前の構成が機能しなかったのか)がわからないため、私自身の答えを受け入れるつもりはありません。
たぶん誰かがキャッシュを機能させる2つの構成の特定の違いを見つけることができます:それは許容できる答えでしょう。