初回アクセス時に静的コンテンツを生成し、2回目以降のアクセスは生成済のコンテンツを返す構成をCloudFront+S3で実現できたので残します。
もっとよい方式があればコメントください。
目的
・URLへの初回アクセス時にコンテンツを生成し、2回目以降は同じ内容のコンテンツを返したい
・サーバレスで実現したい
用途
・検索キーワードを元にコンテンツを生成するなど事前処理が難しい場合
・対象データ量は多いがアクセスされるURLが限定されているためディスク容量を節約したい場合
・コンテンツ生成処理がネックになっていて生成の回数を減らしたい場合
メリット
・サーバレスなのでスケールする
・S3の低冗長化ストレージ(RRS)を使用することでコストを抑えられる
→2016/12の値下げにより、東京リージョンではRRSの方が価格が高いという逆転現象がおこっている
ポイント
- コンテンツ配信処理はCloudFrontとS3で、コンテンツ生成処理はlambdaとAPI Gatewayで実現する(コンテンツ生成処理は既存サーバでも可)
- コンテンツ生成処理ではS3のパスを引数として受けてコンテンツを生成する。生成したコンテンツをS3に置き、その内容をレスポンスする
- S3は静的ウェブサイトホスティングを有効にする
- S3の設定で404レスポンス時に307(Temporary Redirect)を返し、生成処理へリダイレクトする
低冗長化設定でデータがロストした場合は405が発生する1ようなのでこれもリダイレクトする(未検証)
<RoutingRules>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
</Condition>
<Redirect>
<Protocol>https</Protocol>
<HostName>example.com</HostName>
<ReplaceKeyPrefixWith>img?fname=</ReplaceKeyPrefixWith>
<HttpRedirectCode>307</HttpRedirectCode>
</Redirect>
</RoutingRule>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>405</HttpErrorCodeReturnedEquals>
</Condition>
<Redirect>
<Protocol>https</Protocol>
<HostName>example.com</HostName>
<ReplaceKeyPrefixWith>img?fname=</ReplaceKeyPrefixWith>
<HttpRedirectCode>307</HttpRedirectCode>
</Redirect>
</RoutingRule>
</RoutingRules>
- 上記リダイレクトを有効にするため、CloudFrontのOrigin Domain Name に指定するS3のバケット名は、ドロップダウンに表示されるエンドポイント(*.s3*.amazonaws.com)でなくウェブサイトエンドポイント(*.s3-website-*.amazon.com)を指定する。2
-
[重要] CloudFrontのデフォルト設定は307であってもキャッシュするため、2回目以降も生成処理へリダイレクトしてしまう
また、S3で設定するリダイレクトルールではキャッシュをコントロールするヘッダは付与できない
CloudFront側のキャッシュをデフォルトで無効化し、すべてのファイルに個別にキャッシュ設定を入れることでこれを回避する。 設定は以下の通り。- CloudFrontのBehaviorにてObject Cachingを「Customize」に変更、Default TTLを0に設定
- コンテンツ生成処理のS3へのアップロード時に、コンテンツファイルにメタデータとして
Cache-Control max-age=2592000, s-maxage=259200
を追加
注意点
・初回アクセスはコンテンツ生成の時間がかかる
・キャッシュが必要なすべてのコンテンツに明示的にキャッシュコントロールの設定を付与する必要がある
参考URL
- http://qiita.com/komazawa/items/51cbedbc0f2e5be0ed67
- https://cloudpack.media/12607
-
Amazon S3 でオブジェクトの消失が検出された場合、後続の GET または HEAD オペレーション、あるいは消失したオブジェクトをコピー元として使用する PUT Object copy オペレーションは、405 Method Not Allowed エラーになります(AWS Documentation データ消失のリターンコード) ↩