LoginSignup
7
5

More than 5 years have passed since last update.

CloudFrontにおけるオリジンからのHTTP 5xxステータスコードのキャッシュ挙動

Last updated at Posted at 2017-12-20

好きなAWSサービスはCloudFrontのコマコウです。
(本記事は、2017年12月20日時点のCloudFrontの仕様です。)

要点

  • CloudFrontはオリジンからのHTTP 5xxステータスコードを処理する際に、エッジロケーションのオブジェクト有無で挙動が異なる
  • キャッシュの有効期限が切れても、エッジロケーションはオブジェクトを保持し続けることはある
  • エッジロケーションにオブジェクトが無い場合:CloudFrontのカスタムエラーページ設定に従う
  • エッジロケーションにオブジェクトが有る場合:エッジロケーションのオブジェクトをレスポンスし続ける

背景

CloudFrontがオリジンからのHTTP 5xxステータスコード処理する際に、エッジロケーションに保持していたオブジェクトをビューワーにHTTP 200ステータスコードで応答し続けると問題があるシステムはあります。例えば、動的サイト・APIサービスでCloudFrontを利用している構成は注意が必要です。

環境

今回は、LAMP環境で、RDS/EC2(WEBサーバ)/ELB/CloudFrontを利用した環境を例とします。

CloudFrontの挙動

エッジロケーションにオブジェクトが無い場合

  1. ビューワーがリクエストする。
  2. エッジロケーションがオリジンにリクエストをする。
  3. オリジンが5xxエラーをエッジロケーションにレスポンスする。
  4. CloudFrontのカスタムエラーページの設定に従い、ビューワーにレスポンスする。 カスタムエラーページが未設定(デフォルト)の場合、5xxステータスコードをビューワーにレスポンスする。5分間に渡り、エッジロケーションは 5xxステータスコードをキャッシュする。 figure-1.png

エッジロケーションにオブジェクトが有る場合

  1. ビューワーがリクエストする
  2. オブジェクトの有効期限が切れてない場合は、エッジロケーションがオブジェクトをビューワーにレスポンスする。キャッシュの有効期限が切れている場合は、オリジン(ELB・WEBサーバ)にリクエストする
  3. オリジンが5xxエラーをエッジロケーションにレスポンスする
  4. カスタムエラーページのエラーキャッシュ最小 TTL の期間(デフォルトで5分)、エッジロケーションはビューワーに対して、オブジェクトの有効期限が切れていても、エッジロケーションに保持しているオブジェクトをレスポンスし続ける。エラーキャッシュ最小TTLを経過後のリクエストは、再度オリジンにリクエストを行う。
  5. 再度オリジンにリクエストされたオブジェクトが、5xxステータスコードをレスポンスすると、エッジロケーションに保持しているオブジェクトをレスポンスする。
  6. 1~5を繰り返えします。ビューワーにはエッジロケーションからオブジェクトが200ステータスコードでレスポンスされますので、表面上は正常に動作しているようにみえます。 figure-2.png

対策案

CloudFrontが、オリジンからの5xxステータスコードのレスポンスを、ビューワに 200ステータスコードでレスポンスさせない対策について検討しました。各環境によって、最善な方法は異なると思われます。(無作為にインバリデーションを行うと、エッジロケーションから、よしなに200ステータスコードでレスポンスされていたオブジェクトが、5xxステータスコードでレスポンスされますので、サービスダウンする可能性があります。)

  1. デプロイ時にCloudFrontのインバリデーション
    基本的な処理ですが、デプロイ後にインバリデーションを行い、エッジロケーションに保持しているオブジェクトをクリアにする。

  2. オリジン(ELB/WEBサーバ)の5xxエラーを監視モニタリング
    オリジンでHTTP 5xxステータスコードを検知したら、CloudFrontから応答しているレスポンスの確認を行う。5xxステータスコード対策後に、インバリデーションを行う。5xxステータスコードが頻繁に出ないようにエラーハンドリングしておこうね...

3. Lambda@Edgeを利用して、オリジンからHTTP 5xxステータスコードを応答したレスポンスに対して処理を加える。
こちらの対策は、発想段階なので、2017年度の冬休みの宿題とします。
※追記
(2017年12月21日時点)
Lambdaのドキュメントによると、 CloudFront オリジンレスポンスはオリジンが 400 以上の HTTP ステータスコードを返した場合に発火しない とのことです。
Lambda 関数をトリガーできる CloudFront イベント
http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html

参考

上記の挙動は、公式ドキュメントに詳細に記載されております。
CloudFront がオリジンからの HTTP 4xx および 5xx ステータスコードを処理してキャッシュに保持する方法
http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/HTTPStatusCodes.html

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5