Votre approche du proxy des fichiers S3 via Nginx est tout à fait pertinente. Elle résout un certain nombre de problèmes et offre des avantages supplémentaires tels que le masquage des URL, le cache du proxy, l'accélération du transfert en déchargeant SSL/TLS. Vous le faites presque correctement, laissez-moi vous montrer ce qu'il reste à faire pour le rendre parfait.
Pour les requêtes d'exemple, j'utilise le seau S3 et l'URL d'une image mentionnée dans le document commentaire public à la question initiale.
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 qu'il manque Cache-Control mais que 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 d'un navigateur), nous obtenons HTTP 304 avec un Content-Length vide. Une interprétation de cela est que le client (curl dans notre cas) interroge la ressource en disant qu'aucun transfert de données n'est nécessaire à moins que le fichier 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é de tirer parti de la mise en cache du navigateur", cela 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 aussi l'économie de trafic. en utilisant le cache du proxy Nginx.
J'utilise macOS mais la configuration de Nginx fonctionne sous Linux exactement de la même manière sans modifications. Pas à pas :
1. installer Nginx
brew update && brew install nginx
2. configurer Nginx pour qu'il serve de proxy au seau S3, voir la configuration ci-dessous.
3. demander le fichier via Nginx. Veuillez jeter un coup d'œil à la Serveur nous voyons maintenant Nginx plutôt qu'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
Demander le fichier en utilisant le 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
5. demander le fichier en utilisant le cache du proxy de Nginx, veuillez consulter le site suivant X-Cache-Status sa valeur est MISS jusqu'à ce que le cache soit réchauffé après la première 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
Sur la base de Documentation officielle de Nginx Je fournis la configuration Nginx S3 avec 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 du rafraîchissement du contenu des serveurs d'origine
- le paramètre de mise à jour de la proxy_cache_utilisation_stale indique à NGINX de livrer du contenu périmé lorsque les clients demandent un article alors qu'une mise à jour de celui-ci est en cours de téléchargement depuis le serveur d'origine, au lieu de transmettre les demandes répétées au serveur
- avec proxy_cache_lock activé, si plusieurs clients demandent un fichier qui n'est pas à jour dans le cache (un MISS), seule la première de ces demandes est autorisée à passer au serveur d'origine. demandes est autorisée par 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/;
}
}
}
0 votes
Peut-être modifier le Cache-Control pour les objets existants via un script, par exemple. chriskief.com/2014/07/13/réglage du cache-métadonnées 3 .
0 votes
Je ne vois rien dans la configuration de Nginx pour ajouter des en-têtes. De plus, le
proxy_hide_header
sont ignorées, et nginx, par défaut, aurait dû supprimer les directivesServer:
. Donc... êtes-vous sûr que cette requête a été effectivement traitée par Nginx ?0 votes
@Michael-sqlbot Non. Je ne connais presque rien à la configuration des serveurs. Toute aide est appréciée.
0 votes
Vous avez raison. Je pense que la demande n'a pas été traitée par Nginx. Ceci est un exemple de demande de ressources : yanpy.dev.s3.amazonaws.com/img/blog/ Comment puis-je définir l'emplacement ? @Michael-sqlbot
0 votes
Sans savoir quel cadre/environnement vous utilisez, il est difficile de deviner comment les URL de base peuvent être configurées.
0 votes
AngularJS 1.0.7 fonctionnant dans le serveur Nginx.
0 votes
Avez-vous envisagé d'utiliser CloudFront pour cela ? Il est trivial de le configurer avec S3 et il configurera ces en-têtes automatiquement et sera disponible dans le monde entier.
0 votes
Vous pouvez consulter cette implémentation de référence de NGINX utilisant S3 comme proxy avec njs : github.com/nginxinc/nginx-s3-gateway