CloudFrontをS3にホストしたウェブサイトの前段として使っている場合、CloudFrontのキャッシュを削除しても思った通りの動作にならなかったので解決策を調べてみました。
tl;dr
- S3のウェブサイトはデフォルトでURL末尾のスラッシュをindex.htmlとして解釈する。例えば、
- (1)
www.example.com/hoge/
と - (2)
www.example.com/hoge/index.html
- (1)
- CloudFrontのキャッシュはURLそのものに効くので(2)のパスだけでなく(1)のパスをinvalidateしないと想定した動作にならない (っぽい)。
- ドキュメントにしっかり書いてありました (汗)。
flickr photo shared by mikecogh under a Creative Commons ( BY-SA ) license
CloudFrontのキャッシュとInvalidation
前回の記事でAmazon CloudFrontを利用してウェブサイトをSSL化することにしましたが、もう一つの機能としてCDN (Content Delivery Network)というものがあります。というかむしろこっちのほうがメインです。
CDNを使うとインターネット上のコンテンツを効果的に配信することができます。詳しくはWikipedia等を参照してください。
CDNの機能として配信されたコンテンツをキャッシュしておいて配信元のサーバにアクセスする頻度を下げるというものがあります。逆に言うとCDNにキャッシュされているものは常に最新の状態ではないかもしれません。
例えば、このサイトで新しい記事を書いたときにトップページやサイドバーに表示されている最新記事のリストを変更したかったりしますが、それらがキャッシュされてしまっているといくらリロードしても以前の表示のままになってしまいます。
そこで登場するのがinvalidationです。この操作を行うとCloudFrontに対して指定したコンテンツのキャッシュを破棄するように伝えることができます。
自分の場合、ブログ記事を新たに書いたときに少なくともトップページとブログトップ、アーカイブは最新にしておきたかったのでそれぞれに対してinvalidationをしようと思いました。
さて、ほとんどのWebサーバの動作としてURL末尾がスラッシュで終わっているときに指定したファイルを表示するということができます。
S3をウェブサイトとして利用するときも例外ではなく、デフォルトでindex.htmlの内容を表示させることができます。つまり rn4ru.com/
にアクセスしたとき、 rn4ru.com/index.html
の内容が表示されます。
そういうわけで実際に表示されているのはindex.htmlなのだから更新時はそのファイルのみをinvalidateすればいいと思っていました。実はそれだけでは不十分で、末尾スラッシュのほうもinvalidateしなければなりません。
と、ここまで書いておいてもう一度公式のドキュメントを確認したらしっかり書いてありました (汗)。
Browsers and other web applications will resolve both formats to the same directory. However, CloudFront stores public URLs exactly as they appear in the request. If you want to invalidate a directory, you'll need to specify the exact same directory, including or excluding the slash.
(強調筆者)
つまりブラウザのアドレスバーに表示されてるURLとしてキャッシュするということですね。
しかしこの書き方だと末尾スラッシュなしのもinvalidateしないと駄目っぽいですが、ブラウザの挙動をみてるとスラッシュなしはスラッシュありにリダイレクトされてるみたいです。「リダイレクトされる」という動作がキャッシュされてるなら別にそれはそれでいいかなとも思うのですが、詳しい人がいたらアドバイスいただけると嬉しいです。
結論
ドキュメントはちゃんと読みましょう。
Comments
comments powered by Disqus