Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

好きな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

komazawa
2014年11月にcloudpackにジョイン!!好きなAWSサービスはCloudFrontです。もうすぐ30歳
cloudpack
Amazon Web Services (AWS) の導入設計、環境構築、運用・保守をサポートするマネジドホスティングサービス
https://cloudpack.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away