web-dev-qa-db-ja.com

NginxプロキシAmazon S3リソース

いくつかのWPOタスクを実行しているので、PageSpeedはブラウザーのキャッシュを活用することを提案しました。 Nginxサーバーの一部の静的ファイルについては正常に改善しましたが、Amazon S3サーバーに保存されている画像ファイルはまだ見つかりません。

S3の各ファイルを更新していくつかのヘッダーメタタグ(ExpiresおよびCache-Control)を含めることに関するアプローチを読みました。これは良いアプローチではないと思います。私は何千ものファイルを持っているので、これは私にとって実行不可能です。

最も便利なアプローチは、S3ファイルをプロキシするようにNginx 1.6.0サーバーを構成することだと思います。私はこれについて読んだことがありますが、サーバー設定についてはまったく熟練していません。そのため、これらのサイトからいくつかの例を入手しました: https://Gist.github.com/benjaminbarbe/1961db5ffbaad57eff12

私はnginx設定ファイルのサーバーブロック内にこのロケーションコードを追加しました:

#inside server block
location /mybucket.s3.amazonaws.com/ {


        proxy_http_version     1.1;
        proxy_set_header       Host mybucket.s3.amazonaws.com;
        proxy_set_header       Authorization '';
        proxy_hide_header      x-amz-id-2;
        proxy_hide_header      x-amz-request-id;
        proxy_hide_header      Set-Cookie;
        proxy_ignore_headers   "Set-Cookie";
        proxy_buffering        off;
        proxy_intercept_errors on;      
        proxy_pass             http://mybucket.s3.amazonaws.com;
      }

確かに、これは私にとってはうまくいきません。リクエストにヘッダーが含まれていません。そのため、最初にリクエストが場所と一致していないと思います。

Accept-Ranges:bytes
Content-Length:90810
Content-Type:image/jpeg
Date:Fri, 23 Jun 2017 04:53:56 GMT
ETag:"4fd0be549fbcaf9b47c18a15146cdf16"
Last-Modified:Tue, 09 Jun 2015 09:47:13 GMT
Server:AmazonS3
x-amz-id-2:cKsq1qRra74DqVsTewh3P3sgzVUoPR8aAT2NFCuwA+JjCdDZfk7/7x/C0WPjBa51GEb4C8LyAIc=
x-amz-request-id:94EADB4EDD3DE1C1
53
Rober

Nginxを介してS3ファイルをプロキシする方法は非常に理にかなっています。多くの問題を解決し、URLのマスキング、プロキシキャッシュ、SSL/TLSのオフロードによる転送の高速化などの追加の利点があります。あなたはそれをほぼ正しくやって、完璧にするために残っているものを見せてくれ。

サンプルクエリでは、S3バケットと、元の質問の パブリックコメント に記載されている画像URLを使用します。

Amazon S3ファイルのヘッダーの検査から始めます

curl -I http://yanpy.dev.s3.amazonaws.com/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg

HTTP/1.1 200 OK
Date: Sun, 25 Jun 2017 17:49:10 GMT
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Accept-Ranges: bytes
Content-Type: binary/octet-stream
Content-Length: 378843
Server: AmazonS3

Cache-Controlがないことがわかりますが、条件付きGETヘッダーは既に構成されています。 E-Tag/Last-Modifiedを再利用すると(ブラウザのクライアント側キャッシュが機能する方法です)、空のContent-LengthとともにHTTP 304を取得します。クライアントの解釈(この場合はカール)は、サーバーでファイルが変更されていない限り、データ転送は不要であるとリソースに問い合わせます。

curl -I http://yanpy.dev.s3.amazonaws.com/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg 
--header "If-None-Match: 37a907fc5dd7cfd0c428af78f09e95a9"

HTTP/1.1 304 Not Modified
Date: Sun, 25 Jun 2017 17:53:33 GMT
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Server: AmazonS3

curl -I http://yanpy.dev.s3.amazonaws.com/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg 
--header "If-Modified-Since: Wed, 21 Jun 2017 07:42:31 GMT"

HTTP/1.1 304 Not Modified
Date: Sun, 25 Jun 2017 18:17:34 GMT
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Server: AmazonS3

「PageSpeedはブラウザのキャッシュを活用することを提案しました」ということは、Cache = controlがないことを意味します。 S3ファイルのプロキシとしてのNginxは、ヘッダーが見つからないという問題を解決するだけでなく、Nginxプロキシキャッシュを使用してトラフィックを節約します。

私はmacOSを使用していますが、Nginxの設定はLinux上で修正なしでまったく同じように機能します。ステップバイステップ:

1. Nginxのインストール

brew update && brew install nginx

2. NginxをプロキシS3バケットにセットアップします。以下の構成を参照してください

3. Nginx経由でファイルをリクエストします。 Serverヘッダーをご覧ください。AmazonS3ではなくNginxが表示されています。

curl -I http://localhost:8080/s3/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg

HTTP/1.1 200 OK
Server: nginx/1.12.0
Date: Sun, 25 Jun 2017 18:30:26 GMT
Content-Type: binary/octet-stream
Content-Length: 378843
Connection: keep-alive
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Accept-Ranges: bytes
Cache-Control: max-age=31536000

Request the file via Nginx

4. Nginxプロキシと条件付きGETを使用してファイルを要求します。

curl -I http://localhost:8080/s3/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg 
--header "If-None-Match: 37a907fc5dd7cfd0c428af78f09e95a9"

HTTP/1.1 304 Not Modified
Server: nginx/1.12.0
Date: Sun, 25 Jun 2017 18:32:16 GMT
Connection: keep-alive
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Cache-Control: max-age=31536000

Request the file using Nginx proxy with Conditional GET

5. Nginxプロキシキャッシュを使用してファイルをリクエストします。X-Cache-Statusヘッダーを見てください。最初のキャッシュがウォームアップされるまで、その値はMISSです要求

curl -I http://localhost:8080/s3_cached/img/blog/sailing-routes-around-croatia-central-dalmatia-islands/yachts-anchored-paradise-cove-croatia-3.jpg
HTTP/1.1 200 OK
Server: nginx/1.12.0
Date: Sun, 25 Jun 2017 18:40:45 GMT
Content-Type: binary/octet-stream
Content-Length: 378843
Connection: keep-alive
Last-Modified: Wed, 21 Jun 2017 07:42:31 GMT
ETag: "37a907fc5dd7cfd0c428af78f09e95a9"
Expires: Fri, 21 Jul 2018 07:41:49 UTC
Cache-Control: max-age=31536000
X-Cache-Status: HIT
Accept-Ranges: bytes

Request the file using Nginx proxy cache

Nginx公式ドキュメント に基づいて、次のオプションをサポートする最適化されたキャッシュ設定をNginx S3構成に提供します。

  • proxy_cache_revalidateは、NGINXにOriginサーバーからコンテンツを更新するときに条件付きGETリクエストを使用するよう指示します
  • proxy_cache_use_staleディレクティブの更新パラメーターは、Oginサーバーからの更新のダウンロード中にクライアントがアイテムを要求したときに古いコンテンツを配信するようにNGINXに指示します繰り返しリクエストをサーバーに転送する
  • proxy_cache_lockを有効にすると、複数のクライアントがキャッシュ内の最新ではないファイル(MISS)を要求した場合、それらの要求の最初のみがOriginサーバー

Nginx設定

worker_processes  1;
daemon off;

error_log  /dev/stdout info;
pid        /usr/local/var/nginx/nginx.pid;


events {
  worker_connections  1024;
}


http {
  default_type       text/html;
  access_log         /dev/stdout;
  sendfile           on;
  keepalive_timeout  65;

  proxy_cache_path   /tmp/ levels=1:2 keys_zone=s3_cache:10m max_size=500m
                     inactive=60m use_temp_path=off;

  server {
    listen 8080;

    location /s3/ {
      proxy_http_version     1.1;
      proxy_set_header       Connection "";
      proxy_set_header       Authorization '';
      proxy_set_header       Host yanpy.dev.s3.amazonaws.com;
      proxy_hide_header      x-amz-id-2;
      proxy_hide_header      x-amz-request-id;
      proxy_hide_header      x-amz-meta-server-side-encryption;
      proxy_hide_header      x-amz-server-side-encryption;
      proxy_hide_header      Set-Cookie;
      proxy_ignore_headers   Set-Cookie;
      proxy_intercept_errors on;
      add_header             Cache-Control max-age=31536000;
      proxy_pass             http://yanpy.dev.s3.amazonaws.com/;
    }

    location /s3_cached/ {
      proxy_cache            s3_cache;
      proxy_http_version     1.1;
      proxy_set_header       Connection "";
      proxy_set_header       Authorization '';
      proxy_set_header       Host yanpy.dev.s3.amazonaws.com;
      proxy_hide_header      x-amz-id-2;
      proxy_hide_header      x-amz-request-id;
      proxy_hide_header      x-amz-meta-server-side-encryption;
      proxy_hide_header      x-amz-server-side-encryption;
      proxy_hide_header      Set-Cookie;
      proxy_ignore_headers   Set-Cookie;
      proxy_cache_revalidate on;
      proxy_intercept_errors on;
      proxy_cache_use_stale  error timeout updating http_500 http_502 http_503 http_504;
      proxy_cache_lock       on;
      proxy_cache_valid      200 304 60m;
      add_header             Cache-Control max-age=31536000;
      add_header             X-Cache-Status $upstream_cache_status;
      proxy_pass             http://yanpy.dev.s3.amazonaws.com/;
    }

  }
}
99
Anatoly

Nginxがどのモジュールでコンパイルされているかの詳細がなければ、ExpiresおよびCache-Controlヘッダーをすべてのファイルに追加する2つの方法を言うことができます。

Nginx S3プロキシ

これはあなたが尋ねたことです-Nginxを使用して、S3ファイルに期限切れのキャッシュ制御ヘッダーを追加します。

Nginx このset-misc-nginx-moduleが必要です Nginx S3プロキシをサポートし、変更/追加の有効期限、その場でキャッシュ制御を行います。 これは標準の完全ガイドです コンパイルから使用まで、これは buntuサーバーのnginx-extrasの優れたガイド です。これは WordPressの例を含む完全ガイド です。

余分なもののためのS3モジュールがさらにあります。これらのモジュールがないと、Nginxは理解できず、設定テスト(nginx -t)は間違った設定でテストに合格します。 set-misc-nginx-moduleは必要に応じて最低限必要です。あなたが欲しいものは このGithub Gistのより良い例 です。

すべてがコンパイルで使用されるわけではなく、セットアップが本当に少し難しいので、1つのAmazon S3バケット内のすべてのファイルにExpiresおよびCache-Controlヘッダーを設定する方法も書いています。

Amazon S3バケットの有効期限とキャッシュ制御ヘッダー

また、スクリプトまたはコマンドラインを使用して、1つのAWS S3バケット内のすべてのオブジェクトにExpiresおよびCache-Controlヘッダーを設定することもできます。 Githubには、このような無料のライブラリとスクリプトがいくつかあります このようなものバケットエクスプローラーAmazonのツールAmazonのこのドキュメント =および このドキュメント 。そのcp CLIツールのコマンドは次のようになります。

aws s3 cp s3://mybucket/ s3://mybucket/ --recursive --metadata-directive REPLACE \
--expires 2027-09-01T00:00:00Z --acl public-read --cache-control max-age=2000000,public
4
Abhishek Ghosh

アーキテクチャのレビューから、あなたがやろうとしていることは間違った方法です:

  • Amazon S3はおそらく、高可用性キャッシュとして最適化されています。その上に手動ロールプロキシレイヤーを導入することにより、不必要な余分な遅延と巨大な障害点を導入し、S3からもたらされるすべての利点を失うことになります。

  • ファイル数に関するパフォーマンス分析が正しくありません。 S3に数千のファイルがある場合、正しい解決策は、完全に理解していないプロキシメカニズムを手動でローリングする代わりに、S3の必要な属性を変更するワンタイムスクリプトを記述して実行することです。何回も(広告の吐き気)。プロキシを実行することは、おそらくバンドエイドであり、実際には、パフォーマンスを低下させるのではなく、パフォーマンスを低下させる可能性があります(ステートレスの自動化ツールに通知する場合でも)。言うまでもなく、それは不必要なリソースの流出にもなり、実際のパフォーマンスの問題や今後のヘイゼンバグに寄与する可能性があります。


とはいえ、まだヘッダーを追加してプロキシする準備ができている場合、nginxを使用した正しい方法は expires ディレクティブ。

たとえば、適切な場所内のexpires max;ディレクティブの前後にproxy_passを配置できます。

expiresディレクティブは、正しいCache-Controlヘッダーの設定も自動的に処理します。ただし、カスタム応答ヘッダーを手動で追加する場合は、 add_header ディレクティブを使用することもできます。

1
cnst