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
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
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
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
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:
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/;
}
}
}
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
À 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.