CloudFrontキャッシュを使用して、オリジンサーバに対するリクエスト数を抑える構成
AWS SAAの出題範囲の1つでもある、高性能アーキテクチャの設計に関する内容です。
オリジンサーバの前面にCloudFrontを配置し、コンテンツをキャッシュさせ、オリジンサーバのパフォーマンス向上を図ります。
構成する環境
パブリックサブネットにEC2インスタンス(Amazon Linux 2)を設置します。インスタンスにApacheをインストールし、Webサーバとして動作させます。
その前面にCloudFrontを配置し、インスタンスのコンテンツをキャッシュさせます。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートファイルを設置しています。
https://github.com/awstut-an-r/awstut-saa/tree/main/02/005
テンプレートファイルのポイント解説
VPCのDNS機能を有効化する
EC2インスタンスにホスト名でアクセスできるように設定します。
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCidrBlock
EnableDnsHostnames: true
EnableDnsSupport: true
Code language: YAML (yaml)
VPCではさまざまな機能を提供していますが、その内の1つにDNSに関するものがあります。
VPC 内に起動したインスタンスにパブリック IPv4 アドレスがあり、VPC の DNS ホスト名と DNS サポート属性の両方が true に設定されている場合、そのインスタンスはパブリック DNS ホスト名を受け取ります。
VPC の DNS サポート
DNS機能を設定する理由は、EC2インスタンスのパブリックDNSホスト名が必要だからです。
後述のCloudFrontのオリジンサーバの指定では、このパブリックDNSホスト名を使います。
VPCでDNS機能を有効するためには、以下の2つのパラメータをどちらも有効に設定する必要があるとされています。
enableDnsHostnames
パブリック IP アドレスを持つインスタンスが、対応するパブリック DNS ホスト名を取得するかどうか示します。enableDnsSupport
VPC 内の DNS 属性
DNS 解決がサポートされているかどうかを示します。
上記に従い、EnableDnsHostnamesプロパティおよびEnableDnsSupportプロパティにtrueに設定します。
EC2インスタンスにEIPを付与する
EC2インスタンスを確認します。
ポイントは固定アドレスを付与する点です。
Resources:
EIP:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
EIPAssociation:
Type: AWS::EC2::EIPAssociation
Properties:
AllocationId: !GetAtt EIP.AllocationId
InstanceId: !Ref Instance
Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref PublicSubnet
GroupSet:
- !Ref InstanceSecurityGroup
UserData: !Base64 |
#!/bin/bash -xe
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
ec2-metadata -i > /var/www/html/index.html
Outputs:
InstancePublicDnsName:
Value: !GetAtt Instance.PublicDnsName
Code language: YAML (yaml)
インスタンスに固定的にIPアドレスを割り当てます。
先述のパブリックDNSホスト名は、パブリックアドレスに基づいて作成されます。そのためパブリックアドレスが動的に変更されると、それに釣られて、パブリックDNSホスト名も変更される恐れがあります。
固定的にパブリックアドレスを付与するためには、Elastic IPを使用します。Elastic IPを定義後、EC2インスタンスに関連付けます。
CloudFrontのオリジンにEC2インスタンスを設定する
まずCloudFrontのオリジンサーバの指定方法を確認します。
Resources:
Distribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- CustomOriginConfig:
OriginProtocolPolicy: http-only
DomainName: !Ref InstancePublicDnsName
Id: !Ref InstancePublicDnsName
Code language: YAML (yaml)
オリジンサーバの指定は、Originsプロパティで行います。
DomainNameプロパティで、オリジンサーバのドメイン名を指定します。今回はEC2インスタンスのパブリックDNSホスト名を指定します。
CustomOriginConfigプロパティにて、CloudFrontがオリジンサーバにアクセスする際の挙動を変更することができます。今回はオリジンサーバであるEC2インスタンスは、HTTPSではなく、HTTPリクエストをリッスンしています。そのためOriginProtocolPolicyプロパティに「http-only」と設定します。
Idプロパティでオリジンサーバに割り当てるIDを指定します。今回はインスタンスのパブリックDNSホスト名を指定します。この値は、後述のキャッシュ設定で使用します。
CloudFrontのキャッシュ設定
最後にキャッシュ設定を行います。
Resources:
Distribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
CachedMethods:
- GET
- HEAD
Compress: true
ForwardedValues:
Cookies:
Forward: none
QueryString: false
TargetOriginId: !Ref InstancePublicDnsName
ViewerProtocolPolicy: allow-all
DefaultTTL: !Ref CacheTTL
MaxTTL: !Ref CacheTTL
MinTTL: !Ref CacheTTL
Code language: YAML (yaml)
今回はEC2インスタンスだけがオリジンサーバです。そのためDefaultCacheBehaviorプロパティを設定することで、本CloudFrontディストリビューションのデフォルトキャッシュ設定を行います。
AlloedMethodsプロパティで本ディストリビューションで許可するHTTPメソッドを指定します。本プロパティに設定する値は、受け付けるメソッドのパターンによって定められています。
A complex type that controls which HTTP methods CloudFront processes and forwards to your Amazon S3 bucket or your custom origin. There are three choices:
・CloudFront forwards only GET and HEAD requests.
AWS::CloudFront::Distribution DefaultCacheBehavior
・CloudFront forwards only GET, HEAD, and OPTIONS requests.
・CloudFront forwards GET, HEAD, OPTIONS, PUT, PATCH, POST, and DELETE requests.
今回はGETのみ受け付けることとします。よってGETおよびHEADを指定します。
CachedMethodsプロパティも同様です。キャッシュに対応するメソッドに応じて、本プロパティに設定する値が決まります。
A complex type that controls whether CloudFront caches the response to requests using the specified HTTP methods. There are two choices:
・CloudFront caches responses to GET and HEAD requests.
AWS::CloudFront::Distribution DefaultCacheBehavior
・CloudFront caches responses to GET, HEAD, and OPTIONS requests.
こちらもGETおよびHEADを指定します。
TargetOriginIdプロパティで、本キャッシュ設定に対応するオリジンサーバを指定します。今回はEC2インスタンスをオリジンサーバとしますので、先述のOriginsプロパティ内の、Idプロパティで指定した値を、こちらにも指定します。
ViewerProtocolPolicyプロパティで、TargetOriginIdプロパティにアクセスする際に、ユーザーから受け付けるHTTPプロトコルを指定できます。今回はHTTPおよびHTTPSを受け付けます。この場合ですと「allow-all」を指定することで、両者を受け付けることができるようになります。
なお本プロパティは、ユーザー〜CloudFront間のHTTPプロトコルに関する設定です。CloudFront〜オリジンサーバ間に関しては、先述の通り、Originsプロパティの方で設定します。今回はユーザーがHTTP・HTTPSどちらのプロトコルでCloudFront向けに通信を行った場合でも、CloudFrontはHTTPでオリジンサーバと通信を行うという挙動になります。
最後にキャッシュのTTLを設定します。3つのプロパティ(DefaultTTL, MaxTTL, MinTTL)でキャッシュの生存時間を設定可能です。今回はいずれも「60(秒)」とします。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- インスタンスのID:i-08665eb4768e384ec
- インスタンスのパブリックDNSホスト名:ec2-35-74-46-156.ap-northeast-1.compute.amazonaws.com
- CloudFrontディストリビューションのドメイン名:https://d3julxofsz7qa5.cloudfront.net
AWS Management Consoleからも、リソースの作成状況を確認します。
まずEC2インスタンスの状況を確認します。
EIPが割り当てられていることと、パブリックDNSホスト名が有効化されていることがわかります。
次にCloudFrontを確認します。
CloudFrontに割り当てられたドメイン名を確認することができます。
ディストリビューションのオリジンとして、EC2インスタンスが設定されています。
デフォルトのパスパターンにEC2インスタンスが指定されています。
挙動確認1:直接EC2インスタンスにアクセス
準備が整いました。
まずEC2インスタンスに直接アクセスします。
インスタンスから応答が返ってきました。
HTTPリクエスト時の挙動を確認します。
インスタンスのパブリックDNSホスト名にアクセスすると、インスタンスのEIPに向かってトラフィックが流れていることがわかります。
挙動確認2:CloudFront経由でEC2インスタンスにアクセス
最後にCloudFrontに対してアクセスします。
こちらもインスタンスから応答が返ってきました。
HTTPリクエスト時の挙動も確認します。
CloudFrontにアクセスすると、エッジロケーション経由でアクセスしていることがわかります。
キャッシュの項目を見ると、「Miss front cloudfront」とあります。初回のアクセスのため、コンテンツがキャッシュされていなかった他mです。
改めてCloudFront経由でアクセスします。
2回目以降は「Hit front cloudfront」となります。
これはHTTPリクエストに対して、CloudFrontにキャッシュされたコンテンツが返されているということを意味しています。
つまりオリジンサーバであるEC2インスタンスに対しては、リクエストは届かないということになり、サーバのパフォーマンス向上が見込めます。
まとめ
EC2インスタンスの前面に、CloudFrontを配置する構成を確認しました。