web-dev-qa-db-fra.com

Proxy Nginx Ressources Amazon S3

Je suis en train d’exécuter certaines tâches de WPO, alors PageSpeed ​​m’a suggéré de tirer parti de la mise en cache du navigateur. Je l'ai amélioré avec succès pour certains fichiers statiques de mon serveur Nginx, mais mes fichiers image stockés sur le serveur Amazon S3 sont toujours manquants.

J'ai lu une approche concernant la mise à jour de chaque fichier dans S3 pour inclure des métatags d'en-tête (Expires et Cache-Control). Je pense que ce n'est pas une bonne approche. J'ai des milliers de fichiers, ce n'est donc pas faisable pour moi.

Je pense qu’une approche plus pratique consiste à configurer mon serveur Nginx 1.6.0 pour qu’il utilise un proxy pour les fichiers S3. J'ai lu des articles à ce sujet, mais je ne connais pas du tout la configuration du serveur. J'ai donc quelques exemples sur ces sites: https://Gist.github.com/benjaminbarbe/1961db5ffbaad57eff12

J'ai ajouté ce code d'emplacement à l'intérieur de mon bloc serveur dans mon fichier de configuration 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;
      }

Bien sûr, cela ne fonctionne pas pour moi. Aucun en-tête n'est inclus dans mes demandes. Donc, d’abord, je pense que les demandes ne correspondent pas aux emplacements.

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

Votre approche des fichiers proxy S3 via Nginx est très sensée. Il résout un certain nombre de problèmes et offre des avantages supplémentaires tels que les URL de masquage, le cache de proxy, l’accélération du transfert en déchargeant SSL/TLS. Vous le faites presque correctement, laissez-moi vous montrer ce qui reste pour le rendre parfait.

Pour des exemples de requêtes, j'utilise le compartiment S3 et une URL d'image mentionnée dans le commentaire public à la question d'origine.

Nous commençons par inspecter les en-têtes des fichiers 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

Nous pouvons voir que Cache-Control est manquant, mais les en-têtes GET conditionnels ont déjà été configurés. Lorsque nous réutilisons E-Tag/Last-Modified (c'est ainsi que fonctionne le cache côté client du navigateur), nous obtenons HTTP 304 ainsi que Content-Length vide. Une interprétation de cela est client (curl dans notre cas) interroge la ressource en indiquant qu'aucun transfert de données n'est requis à moins que le fichier n'ait été modifié sur le serveur:

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 ​​a suggéré d'utiliser la mise en cache du navigateur", ce qui signifie que Cache = control est manquant. Nginx en tant que proxy pour les fichiers S3 résout non seulement le problème des en-têtes manquants, mais enregistre également le trafic à l'aide du cache de proxy Nginx.

J'utilise macOS mais la configuration de Nginx fonctionne sur Linux exactement de la même manière, sans modifications. Pas à pas:

1. Installer Nginx

brew update && brew install nginx

2. Configurez Nginx sur le compartiment proxy S3, voir la configuration ci-dessous

3. Demander le fichier via Nginx. Veuillez regarder l'en-tête Server , nous voyons maintenant Nginx plutôt que Amazon S3:

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.Request le fichier en utilisant un proxy Nginx avec GET conditionnel:

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.Requestez le fichier en utilisant le cache du proxy Nginx, consultez l'en-tête X-Cache-Status , sa valeur est MISS jusqu'à ce que le cache soit réchauffé après le premier demande

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

Sur la base de documentation officielle de Nginx , je fournis à la configuration de Nginx S3 des paramètres de mise en cache optimisés qui prennent en charge les options suivantes:

  • proxy_cache_revalidate indique à NGINX d'utiliser des requêtes GET conditionnelles lors de l'actualisation du contenu des serveurs d'origine.
  • le paramètre update de la directive proxy_cache_use_stale indique à NGINX de fournir du contenu obsolète lorsque les clients demandent un élément alors qu'une mise à jour le télécharge depuis le serveur d'origine. de transmettre des demandes répétées au serveur
  • avec proxy_cache_lock activé, si plusieurs clients demandent un fichier non présent dans le cache (MISS), seule la première de ces demandes est autorisée jusqu'à le serveur d'origine

Configuration de 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

Sans les détails des modules avec lesquels Nginx est compilé, nous pouvons dire deux manières d'ajouter des en-têtes Expires et Cache-Control à tous les fichiers.

Nginx S3 proxy

C’est ce que vous avez demandé: utiliser Nginx pour ajouter des en-têtes de contrôle de cache et d’expiration sur les fichiers S3.

Nginx ce set-misc-nginx-module est nécessaire pour prendre en charge le proxy Nginx S3 et la modification/l'ajout expire, le contrôle du cache à la volée. Ceci est un guide complet standard de la compilation à l'utilisation, c'est excellent guide pour nginx-extras sur le serveur Ubunt . Ceci est guide complet avec exemple avec WordPress .

Il y a plus de modules S3 pour des choses supplémentaires. Sans ces modules, Nginx ne comprendra pas et le test de configuration (nginx -t) passera le test avec une configuration incorrecte. set-misc-nginx-module est le minimum pour vos besoins. Ce que vous voulez a meilleur exemple sur ce Github Gist .

Comme tous ne sont pas utilisés avec la compilation et que la configuration est vraiment un peu difficile, j'écris également le moyen de définir les en-têtes Expires et Cache-Control pour tous les fichiers d'un même compartiment Amazon S3.

Expiration du compartiment Amazon S3 et en-tête Cache-Control

En outre, il est possible de définir les en-têtes Expires et Cache-Control pour tous les objets d'un compartiment AWS S3 avec un script ou une ligne de commande. Il existe plusieurs bibliothèques et scripts gratuits sur Github comme celui-ci , explorateur de sea , outil d'Amazon , cette documentation d'Amazon = et cette doc . La commande sera comme ceci pour cet outil CLI cp:

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

À partir d’une revue architecturale, ce que vous essayez de faire est une mauvaise façon de procéder:

  • Amazon S3 est probablement optimisé pour constituer un cache à haute disponibilité; en ajoutant une couche de proxy roulée à la main, vous introduisez simplement un retard supplémentaire inutile et un énorme point de défaillance, et vous perdez également tous les avantages qui découleraient de S3.

  • Votre analyse de performance en ce qui concerne le nombre de fichiers est incorrecte. Si vous avez des milliers de fichiers sur S3, la bonne solution serait d'écrire un script unique pour modifier les attributs requis sur S3, au lieu de lancer manuellement un mécanisme de proxy que vous ne comprenez pas parfaitement et qui serait exécuté. plusieurs fois (ad nauseam). Faire le mandataire serait probablement un pansement et, en réalité, diminuerait probablement les performances, mais ne les augmenterait pas (même si vous obteniez un outil automatisé sans état, vous diriez le contraire). Sans compter que cela constituerait également un gaspillage inutile de ressources et pourrait contribuer à des problèmes de performances réels et à des problèmes ultérieurs.


Cela dit, si vous souhaitez toujours ajouter des en-têtes au proxy, la meilleure façon de le faire avec nginx serait d'utiliser la expires directive.

Par exemple, vous pouvez placer expires max; avant ou après votre directive proxy_pass à l'emplacement approprié.

La directive expires prend automatiquement en charge de définir un en-tête correct pour Cache-Control; mais vous pouvez également utiliser la directive add_header si vous souhaitez ajouter manuellement des en-têtes de réponse personnalisés.

1
cnst