Webサイトのレスポンスが速くなるほど、ページビューが増加し、カスタマーエクスペリエンスが向上し、商品購入などのコンバージョン率も高まる。このことが多くの調査で明らかになっています。

 コーポレートサイトのパフォーマンスを高めるため、AWSのCDN(Content Delivery Network)サービスを利用してコンテンツ配信を高速化する方法を解説します。

 一般にCDNは世界中に設置されたデータセンターに、コンテンツをキャッシュすることにより、そのコンテンツをリクエストしたユーザー(リクエスター)に低レイテンシーで配信する仕組みです(図1)。

図1●CloudFrontによるキャッシュの効果
[画像のクリックで拡大表示]

 AWSは「Amazon CloudFront」と呼ぶCDNサービスを提供しています。CloudFrontの導入に、アーキテクチャーの変更は必要ありません。CloudFrontのセットアップとDNS(Domain Name System)の変更をすれば済みます。

 簡単にDNSを変更するため、ここではAWSのDNSサービスAmazon Route 53を使います。Route 53では、ドメイン管理などを簡素化できます。

 CloudFrontの機能を詳しく見ていきましょう。

2段階のキャッシュ機構

 Amazon CloudFrontはCDNとして、静的および動的なWebコンテンツ(.html、.css、.php、画像ファイルなど)をキャッシュします。「エッジロケーション」と呼ぶ、世界に配置したデータセンターからコンテンツを配信します。

 CloudFrontを導入すると、ユーザーからのリクエストはレイテンシーの最も短いエッジロケーションにルーティングされます。そのエッジロケーションにコンテンツがキャッシュされている場合、そこから直ちに配信します。キャッシュされていない場合は、WebサーバーのEC2インスタンスやS3バケットなど(オリジンと呼ぶ)からコンテンツを取得します。

 CloudFrontでは、エッジロケーションとは別に「リージョン別エッジキャッシュ」と呼ぶCDNデータセンターを展開しており、追加料金なしで利用できます。リージョン別エッジキャッシュは、エッジロケーションとオリジンの間(ユーザーから見るとエッジロケーションの奥)に位置します。エッジロケーションよりキャッシュ容量が大きいので、より長くキャッシュに残ります。より多くのコンテンツがユーザーの近くに保持され、CloudFrontがオリジンまでコンテンツを取りに行く必要がなくなるたるため、ユーザーに対するパフォーマンスが全般的に向上します。

 つまりCloudFrontはエッジロケーション、リージョン別エッジキャッシュという2段階のキャッシュ機構を備えます。2019年8月時点でエッジロケーションは176カ所、リージョン別エッジキャッシュは11カ所です。

 CloudFrontはマネジメントコンソールやAPIによって、すぐに利用を開始できます。従量課金なので、利用を停止すれば課金が止まります。

 CloudFrontを利用する手順を簡単に示します。

 まずCloudFrontというサービスの実体「ディストリビューション」を作成しオリジンを設定します。ディストリビューションには「Webディストリビューション」と「RTMPディストリビューション」があります。

 Webディストリビューションは、Webコンテンツの配信に利用します。ディストリビューションごとに複数のオリジンを設定でき、最大10個のS3バケットと「カスタムオリジン」(EC2インスタンスやオンプレミス環境などのHTTPサーバー)を組み合わせられます。

 RTMPディストリビューションは、ストリーミング配信を行う際に選択します。この場合のオリジンはS3バケットにする必要があります。

 どちらのディストリビューションでも、作成すると、ドメイン名として「xxxx.cloudfront.net」が割り当てられます。このドメインはコンテンツ配信にそのまま使用できます。例えば、オリジンにある/images/image.jpgという画像ファイルを配信する場合、CloudFrontのドメイン名を使用すると、このファイルのURLは「http://xxxx.cloudfront.net/images/image.jpg」となります。

 CloudFrontのドメイン名の代わりに、CNAMEのエイリアスを指定して、独自ドメインで使用することもできます。例えば「www.example.com」という独自ドメインを使用する場合、ディストリビューションの設定画面からディストリビューションに代替ドメイン名(CNAMEs)を追加し、CloudFrontディストリビューションにドメイン名のDNSクエリーをルーティングするように、DNS設定でCNAMEレコードを作成します。この設定にすることにより、「http://www.example.com/images/image.jpg」というURLでコンテンツを配信できるようになります。

Webサイトを高速化するチューニング

 CloudFrontの効果を上げるため、キャッシュのヒット率が高まるようにチューニングする方法を説明します。

 CloudFrontではパス(URL)ごとに、Cache-Controlヘッダーによって、オリジンにファイルの更新バージョンがあるかどうかをチェックする頻度を設定できます。

 チェック頻度のデフォルト値は24時間です。ファイルがそれほど頻繁に変更されない場合は、チェック頻度をもっと長めに設定します。

 例として、「/css/base.css」という頻繁には変更されないファイルにアクセスするアプリケーションの実装を考えます。このとき、「/css/base.css?version=1」のようにクエリーストリングにバージョン情報を付けてアクセスします。さらにオリジンのファイルを更新した際は、「/css/base.css?version=2」のようにクエリー文字列のバージョン情報を変更します。

 CloudFront側ではキャッシュする期間を1カ月など長めに設定しておき、クエリー文字列が異なる場合、別のオブジェクトとして扱う(別々にキャッシュする)ように設定します。こうすることで、ほぼファイルはキャッシュされたエッジロケーションから配信されます。

 動的なコンテンツも、短期間であればキャッシュ可能な場合もあります。画像やJavaScript、CSS、動的コンテンツなどのファイルの種類によって、細かく最適なチェック頻度を設定し、キャッシュヒット率を高めます。

 反対にCloudFrontを使用していると、キャッシュされたファイルを新しいものに更新したい、削除したいという場合もあります。キャッシュされたファイルを失効させる方法は三つあります。

 一つめはTTL(有効期限)を設定する方法です。ただし有効期限を迎えたとき、即座にキャッシュが更新されるわけではありません。ユーザーからリクエストが来て初めて、オリジンからファイルを取得しエッジロケーションのキャッシュを更新します。キャッシュを即時更新する必要がなければ、TTLを設定するのが最も簡単です。

 二つめは、前述のバージョン管理機能を実装し、URLのクエリー文字列を変更する方法です。ユーザーのブラウザーでのキャッシュによって、オリジンのファイルが更新されても表示内容が変わらない、という問題を回避できます。

 三つめの方法は「Invalidation」という無効化指示です。CloudFrontのキャッシュからファイルが削除されます。具体的には、個々のオブジェクトのパスまたはワイルドカードで終わるパスのどちらかを指定します。ワイルドカードを利用すれば、1回で複数のファイルをまとめて削除できます。Invalidationは1カ月当たり1000回まで無料ですが、それ以降は課金が発生します。

CloudFrontの独自SSLサポート

 CloudFrontディストリビューションにデフォルトで割り当てられる「xxxx.cloudfront.net」のドメインは、SSLをサポートしています。そのため特に設定せずとも、HTTPSでのアクセスが可能です。

 CloudFrontは独自SSL証明書に対応しており、独自のドメイン名を使えます。独自ドメインでSSLを利用する方法には、「Server Name Indication(SNI)独自SSL」と「専用IP独自SSL」があります。

 SNI独自SSLでは、Transport Layer Security(TLS)プロトコルのSNI拡張機能を使います。複数のドメインで同じIPアドレスを介してSSLトラフィックを処理します。

 SNI独自SSLは無料ですが、一部の古いWebブラウザーはSNIをサポートしていません。SNIをサポートしないブラウザーにもコンテンツを配信するには、有料の専用IP独自SSL機能を使用します。これを使うと、CloudFrontエッジロケーションごとに、SSLコンテンツを提供するための専用IPアドレスが割り当てられます。課金は、CloudFrontディストリビューションに関連付けた独自SSL証明書ごとに月額600ドル(税別)です。

 CloudFrontはSSL/TLSをベースにして、クライアントとの通信、オリジンとの通信のセキュリティを高める付加機能をそれぞれ備えています。

 クライアントとの通信では、セッションごとに暗号鍵を生成する「Perfect Forward Secrecy(PFS)」、クライアント(ブラウザーなど)からのSSL証明書の失効ステータス照会を不要にしてTLS/SSLハンドシェイクの時間を短縮する「Online Certificate Status Protocol(OCSP) Stapling」という機能を利用できます。

 オリジンとの間の通信においては、プロトコルをHTTPSに限定する機能があります。クライアントがHTTPで接続してきた際、HTTPSにリダイレクトするか、HTTPステータスコード403を返すかのどちらかを選択できます。

 CloudFrontからオリジンにリクエストを転送するとき、カスタムヘッダーを追加したり、既存のリクエストヘッダーの値を上書きしたりすることも可能です。カスタムヘッダーを含むリクエストだけを、オリジンが受け取るように設定してセキュリティを強化できます。

CloudFront経由でS3のコンテンツを配信

 S3バケットから画像やCSSといった静的ファイルを配信すると、EC2インスタンスのWebサーバーから配信するより、ネットワーク帯域の考慮が不要になる、可用性が高くなる、管理が容易になるといった利点があります。さらにS3バケットのコンテンツをCloudFront経由で配信することにより、コストと遅延が低減します。

 S3バケットをCloudFrontディストリビューションのオリジンとして使用する際、S3バケット内のオブジェクトの読み取り権限を全てのユーザーに付与するのが通例です。その場合、世界中の全ユーザーがS3バケットのオブジェクトにアクセスできます。

 ここでCloudFrontではユーザーにS3のURLを公開しませんが、例えば誰かがS3内の特定オブジェクトへの直接リンクを公表した場合、不特定のユーザーがS3オブジェクトに直接アクセスできるようになります。

 S3への直接アクセスを許すと、CloudFrontで取得するアクセスログが不完全になります。さらに、プライベートなコンテンツをCloudFront経由で配信する場合は、不都合が生じます。

 そこで有効なのが「CloudFrontオリジンアクセスアイデンティティ(OAI)」です。ユーザーに成り代わってS3バケットのオブジェクトにアクセスします。

 OAIは、CloudFrontコンソールまたはCloudFront APIで作成します。さらにS3コンソールで、S3バケットポリシーを編集し、作成したOAIからのみS3バケットへのアクセスを許可するよう設定します。

 この設定をしておくと、ユーザーがCloudFrontを経由してS3バケットのオブジェクトにアクセスすれば、OAIがユーザーの代わりにオブジェクトを取得します。ユーザーがS3バケットに直接アクセスしてきたら拒否します。ユーザーにはS3バケットへのアクセス権限がないためです。

 ここまで、誰でもアクセス可能なコンテンツを前提としていました。会員のみが閲覧できるようなプライベートなコンテンツは、どうすればS3バケットから安全に配信できるでしょうか。

 それには、2-2で取り上げたS3の署名付きURL機能を利用します。APサーバーなどでユーザー認証を行い、認可されたユーザーに数分程度の有効期限を付けた署名付きURLを返すことで、アクセス可能にします。

 署名付きURLは、特定のユーザーだけにCloudFront経由でS3バケットのコンテンツを配信する場合にも利用できます。前述の仕組みと同じです。APサーバーなどでユーザーを認証したうえで、そのユーザーに有効期限を設けた署名付きURLを返せばよいのです。

 今回の内容の理解度を確かめる設問を以下に載せました。ぜひ挑戦してください。

■設問1

 Amazon CloudFrontについて説明した文章として正しいものはどれですか(当てはまるものを全て選択)。

  1. 静的コンテンツ以外に動的コンテンツも配信できる
  2. Server Name Indication(SNI)独自SSL、専用IPアドレス独自SSLをどちらも無料で利用できる
  3. SSLv3、TLSv1.0、TLSv1.1、TLSv1.2に対応している(一部対応を含む)
  4. Amazon EC2やAmazon S3などのAWSリソースのほか、オンプレミス(自社所有)環境のWebサーバーもオリジンとして使用できる

解答・解説は以下を参照。

□設問1の答:A、C、D

 Amazon CloudFrontは、グローバルなCDN(Content Delivery Network)です。エッジロケーションと呼ばれる世界各地の拠点にコンテンツをキャッシュし、ユーザーへ高速に配信します。頻繁にアクセスされるコンテンツをCloudFrontから配信することで、バックエンドのサーバーの負荷を軽減できます。機能の特徴を押さえておきましょう。

 CloudFrontでは、HTML、CSS、画像ファイルなどの静的コンテンツのほか、Webアプリケーションから動的に生成されるコンテンツや動画の配信も可能です。ファイル拡張子などでパターンマッチングを行い、対象コンテンツのオリジンやキャッシュ有効期限を設定できます。よってAは正解です。

 クライアントとCloudFrontとの間、CloudFrontとオリジンとの間では、SSLやTLSによる通信を行えます。TLSの対応バージョンは1.0、1.1、1.2です。SSLv3も一部サポートし、モバイル端末などTLSの上位バージョンに対応していないクライアントからのアクセスにも対応できます。Cも正解です。

 オリジンとして、EC2やS3などのAWSリソースのほか、AWS外のWebサーバーも指定できます。Dも正解です。

 SNI独自SSLは無料ですが、専用IPアドレス独自SSLは有料です。従ってBは誤りです。

堀内 康弘(ほりうち・やすひろ)
モビンギ 取締役、M&Aナビ 技術顧問
ブイキューブ、gumiを経て、2012年3月にアマゾン データ サービス ジャパン(現・アマゾン ウェブ サービス ジャパン)入社。テクニカルエバンジェリストとして活躍。2014年10月に退職し、2015年1月モビンギ 取締役に就任。2019年2月からM&Aナビ 技術顧問を兼務。トレノケートでAWS公式トレーニングの講師を務める。
三浦 美緒(みうら みお)
トレノケート ラーニングサービス本部 ラーニングサービス第1部 技術教育エンジニア
外資系ITベンダーでオープン系エンタープライズシステムの運用監視環境の設計、構築に従事した後、2002年より現職。Linux、Apache、BINDなどのトレーニング企画、提案、実施を担当。近年はAWS認定インストラクターとして研鑽中。
出典:『Amazon Web Services エンタープライズ基盤設計の基本』(日経BP社)の第5章を改編
記事は執筆時の情報に基づいており、現在では異なる場合があります。