Forcer CloudFront à transmettre le dernier fichier HTML de S3

13

Contexte

J'héberge un site statique sur S3, avec CloudFront au-dessus. Le problème que j'ai est avec mes fichiers HTML.

Selon la FAQ de CloudFront :

Amazon CloudFront utilise ces en-têtes de contrôle du cache pour déterminer la fréquence à laquelle il doit vérifier l'origine pour une version mise à jour de ce fichier

Ce que j'ai fait jusqu'à présent

Dans cet esprit, j'ai défini les fichiers HTML de mon compartiment S3 pour les ajouter aux en-têtes suivants:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: Fri, 01 Jan 1990 00:00:00 GMT

Lors de mon premier appel à mon samplefile.htm, je vois les en-têtes de réponse suivants (j'ai exclu les en-têtes évidents (par exemple Content-Type) afin de rester au point:

Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Date:Sat, 10 Dec 2011 14:16:51 GMT
ETag:"a5890ace30a3e84d9118196c161aeec2"
Expires:Fri, 01 Jan 1990 00:00:00 GMT
Last-Modified:Sat, 10 Dec 2011 14:16:43 GMT
Server:AmazonS3
X-Cache:Miss from cloudfront

Comme vous pouvez le voir, mon en- Cache-Controltête est là-dedans. Le problème est que si je mets à jour ce fichier et le rafraîchis, j'obtiens le contenu mis en cache (plutôt que le dernier fichier), et je peux voir que CloudFront sert sa version mise en cache en regardant les en-têtes de réponse:

X-Cache:Hit from cloudfront

Résumé / question

Compte tenu de ce qui précède, comment puis-je obtenir la récupération automatique du dernier HTML lors de l'utilisation de CloudFront?

Selon sa FAQ, je devrais être capable de le faire avec des en-têtes Cache-Control, mais je n'arrive pas à faire fonctionner cela.

Suite aux réponses ci-dessous

À la fin, j'ai décidé de changer mon www CNAME pour pointer directement vers mon compartiment S3. Puis ajouté un nouveau CNAME appelé "statique", qui pointe vers CloudFront.

Cela signifie que HTML est directement de S3, qui a ensuite toutes ses références CSS / JS / IMG pointant vers static.mydomain.com

isNaN1247
la source

Réponses:

6

Premièrement, le but de Cloudfront est de servir du contenu mis en cache - si vous essayez de servir du contenu non mis en cache à partir de Cloudfront, il est plus lent que de le servir directement à partir de S3, dans presque tous les cas (quelque chose comme le contenu en streaming serait l'exception). Réfléchissez un instant à ce qui doit se produire pour servir le contenu de Cloudfront - il doit être récupéré du serveur d'origine vers un emplacement qui est géographiquement proche de l'utilisateur - ce qui signifie que pour une demande où Cloudfront doit récupérer le contenu du serveur d'origine , vous ajoutez une latence supplémentaire à la demande et l'utilisateur reçoit le contenu plus lentement. Ce n'est qu'une fois que le contenu est disponible à l'emplacement périphérique que les requêtes suivantes sont plus rapides.

La meilleure approche pour résoudre ce problème consiste à modifier vos noms de fichiers lorsque vous mettez à jour une page - cela obligera Cloudfront à récupérer le nouveau contenu. Encore une fois, gardez à l'esprit que Cloudfront est généralement utilisé pour les fichiers multimédias (y compris les images) et le style / javascript - et pas tellement pour le html. Essentiellement, vous auriez votre code HTML sur S3 et vos images sur Cloudfront - avec toutes les modifications que vous apportez, vous pouvez changer le nom du fichier sur Cloudfront (par exemple fichier-v1.jpg, fichier-v2.jpg, etc.). Une autre méthode courante consiste à inclure une chaîne de requête avec des informations de version.

Gardez également à l'esprit que Cloudfront ne propose pas de contenu compressé - ce qui peut entraîner une réponse plus lente que celle d'un serveur normal (bien que, dans votre cas, S3 n'identifie pas non plus les navigateurs compatibles gzip).

Enfin, si vous le souhaitez, vous pouvez utiliser l'invalidation pour forcer Cloudfront à supprimer sa copie existante et à en récupérer une nouvelle sur le serveur d'origine. Notez cependant que Cloudfront ne vous donne que 1000 invalidations gratuites par mois, après quoi le coût est de 0,005 $ / invalidation.

Le temps le plus court pour Cloudfront de conserver le contenu est de 1 heure , bien que la valeur par défaut soit de 24 heures. J'essaierais donc de définir l'âge max à au moins 3600. Considérez également un en-tête s-maxage (pour le contenu partagé - c'est-à-dire proxy). Amazon recommande ce didacticiel de mise en cache.

Il y a eu un problème récent , corrigé il y a quelques jours

cyberx86
la source
La raison du blocage de CF sur S3 vient de Werner Vogels le mentionnant lui-même dans son article de blog allthingsdistributed.com/2011/02/website_amazon_s3.html . Je pourrais envisager de router le html directement depuis s3 comme vous le dites. Une remarque mineure: l'ajout d'une chaîne de requête à la fin des fichiers pour le contournement du cache n'est pas une bonne idée car cela peut empêcher certains proxy de mettre en cache.
isNaN1247
Ce mec semble utiliser l'invalidation sur chaque téléchargement qui semble exagéré jmlacroix.com
isNaN1247
1
Les chaînes de requête ne fonctionneront pas avec Cloudfront - il ne mettra pas en cache les fichiers, mais elles peuvent être efficaces si vous diffusez votre contenu directement. Le HTML de S3 serait votre meilleur pari. Vous ne voulez certainement pas tout invalider à chaque téléchargement, mais invalider les fichiers qui ont été modifiés n'est pas sans mérite dans certains cas. Les avantages de Cloudfront ne deviennent vraiment pertinents que sur les sites très fréquentés - pour votre site moyen, S3 peut même offrir de meilleures performances (essayez les deux et voyez - en particulier pour les petits objets, Cloudfront peut être lent).
cyberx86
2
Cloudfront prend désormais en charge la compression Gzip. Annonce ici .
Greg Sadetsky
@ les limites de cyberx86 sont différentes de nos jours: The minimum expiration time CloudFront supports is 0 seconds for web distributions and 3600 seconds for RTMP distributions. docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/…
xvga
20

Je pense que les réponses jusqu'à présent, bien que correctes à l'époque, sont désormais obsolètes, car Cloudfront prend désormais en charge un TTL minimum de 0, et la tentative initiale du PO d'utiliser cache-age = 0 devrait maintenant fonctionner.

Vous voudriez voir s'il faut utiliser ces autres en-têtes de contrôle de cache, en termes de s'ils produiront le résultat que vous recherchez - vous n'aurez peut-être besoin que de max-age. Ce que vous voulez probablement, c'est que Cloudfront vérifie S3 pour voir si le fichier HTML a changé. Si tel est le cas, Cloudfront peut récupérer et renvoyer le nouveau fichier. Sinon, il peut servir le client à partir de son cache existant (conserver la bande passante S3 et servir le client plus rapidement et plus localement).

Le but de Cloudfront est de servir du contenu mis en cache, oui, mais maintenant cela inclut du contenu qui change parfois, mais peut être mis en cache s'il n'a pas changé.

Les chaînes de requête PS fonctionnent également avec Cloudfront maintenant (si vous configurez un `` comportement '' pour l'origine pertinente - une autre nouvelle fonctionnalité), mais certains mandataires peuvent toujours ne pas mettre en cache les fichiers avec des chaînes de requête.

Amazon Developer Guide: Expiration 1

Andy Nash
la source
-1

Vous ne savez pas comment CloudFront traite l'en-tête comme vous en avez un, mais si vous ne spécifiez aucun en-tête, le délai par défaut pour actualiser les objets est de 24 heures.

L'une des choses que vous pouvez faire pour actualiser les objets est d'invalider le contenu. Consultez le lien ci-dessous pour plus d'informations. http://blog.cloudberrylab.com/2010/08/how-to-manage-cloudfront-object.html

Jeff
la source