ページ表示速度高速化のためCloudFrontを導入しようとして断念した話

CDNとはContents Delivery Networkの略でウェブコンテンツの配信を高速化する技術です。

当サイトもページ表示速度高速化のためCloudFrontを導入しようと検討してみたのですが、サイトの構成上難しい部分もあって一旦断念しました。

 


ユーザーがアクセスしやすい環境を

71245c8250b2dac26c83d716cb4d5743_m

5月に開設した当サイトも順調にアクセスが増え、10月のアクセス数は10,000PV程になりました。

コンテンツを増やせばこのままPVも順調に増えていくのでしょうが、Wordpressを使用しているためページ表示速度が遅く、直帰率が高いという問題があります。

月1万PVくらいのアクセス量ならサーバーによる503エラー(アクセス過多による接続制限)を吐く事はまずないのでしょうが、ページの表示速度が遅い事はアクセスビリティが悪いという事であり検索エンジンからの評価も良くはなりません。

特に、本サイトはゆとりずむさんのブログ分類によると「情報提供型」に最も近いので、本サイトの基本戦略はロングテールを主軸としたコンテンツ作りと、検索流入を対象としたSEO、関連するコンテンツへの回遊率を上げるとしています。(実際アクセスのほとんどは検索流入です)

この中でも回遊率を上げる問題については、ページ表示速度が遅いことは致命的なネックになります。

操作開始時間が1秒のサイトと3秒のサイトを比較しても、3秒のサイトは1秒のサイトに比べ、ページビューが22%低下、コンバージョン率は38%低下、直帰率は50%上昇してしまうというデータがあります
参考:サイト表示が2秒遅いだけで直帰率は50%増加!

とも言われている通り、この先もコンテンツを増やしサイトの回遊率を増やすのであればページ表示速度の向上は必須となります。

実際、本サイトVOLTECHNOのページ表示速度は遅く、googleアナリティクスのサイト速度サマリーは平均7.56秒となっています、これは遅い。

ページ表示速度の高速化手法

48a6de717d604813bc996fd9da712aef_m

ページ表示速度の高速化には様々な方法がありますが、ページ表示速度を上げる手法を大きく分けると「Webサイトを軽量化する」「サーバーを増強する」という2つの方法に分類できるそうです。

本サイトでの具体的な例を挙げると下記のような方法になります。

  • WordPressの最適化 [サイト軽量化]
    • WordPressは動的にページを生成するため、ウィジェットやプラグインを追加するとその分処理が増えてサイトが重くなります
    • 使わないプラグインやアクセスの低いウィジェットなどは随時削除中
    • 一時期、静的キャッシュプラグインなどを導入してレスポンスを早くしていましたが、一部閲覧環境でサイト表示がおかしくなる事があったため停止してます。
  • Google PageSpeedの改善 [サイト軽量化]
    • 主な評価項目は画像サイズの最適化やhtml,cssのコードの縮小です。
    • 画像サイズやコードは少しづつ修正中、しかしスコア低下の一番の原因はサーバー応答時間らしいので根本的な解決にはならず
  • ホスティングサーバーの変更 [サーバー増強]
    • 借りてるレンタルサーバーをより早いものに変更することです、
    • サーバー応答時間の問題には最も効果があるはず。しかし裏では本サイト以外のサービスも走っているため移転は厳しめ(というかそのせいで遅い気も…)
  • VPSへの移行 [サーバー増強]
    • ↑のホスティングサーバーの変更と似たような対策案です。実は既に借りているVPSがあります。しかし、これはプライベートな用途で使っているものであり、既にスペックギリギリまで使ってたりします。また現時点でセキュアなhttpサーバーを構築する自信もありません。
  • CDNの導入 [サーバー増強]
    • Webサイトのコンテンツを本来のサーバーとは別のサーバーにキャッシュし、そこから読み込ませることでサーバーの負荷を下げる技術です。本サイトは静的なwebコンテンツがほとんどなので、効果は十分見込めそう。

私はPHPやJavaSprictを殆ど触ったことない人間なので、現時点でコードの縮小やjQueryについて適切な対応をとることができません

そうなると現時点ではサーバーを増強するしか手段がないのですが、サーバーを借りるのもタダではありません。お金がかかるのです。

一応、アドセンスやアソシエイトは設置していますが、ノービスクラスの本サイトの広告収入額では現在のサーバー環境の維持で手いっぱいです。現時点ではさくらのレンタルサーバー プレミアムVPSへの移行は厳しめです。

このような問題点に対して、最も期待できそうなのはCDNの導入です。

CDNとは

cdn

さて、CDNとは具体的にどのようなサービスなのでしょうか。

CDNとは略称であり、正式な名前はコンテンツ・デリバリー・ネットワーク(Contents Delivery Network)と言います。CDNを導入するとWEB高速化・サーバー負荷分散・冗長性といった面で大きなメリットがあります。導入の効果の感じを聞くとブロードバンド時代(この単語も既に死語ですね)の先端技術な感じもしますが、CDNは90年代のダイヤルアップ時代に考案された実績のある技術です。

肝心のCDNの仕組みは、ざっくりと言ってしまえば単にキャッシュしたファイルを配信するだけの技術です。

CDNが通常のサーバーと異なるポイントは「最も近い場所にあるサーバーを自動で選択し配信する」という事です。単純に距離が近いという事は応答速度が速くなるという事とほぼイコールとも言えます。また、CDNを提供するサーバーは帯域も広く、コンテンツの高速配信と素早い応答速度が期待できます。

特に本サイトは変化の少ない動的コンテンツで満たされているサイトですので、これを静的コンテンツ的な扱いにしてCDNで配信させてしまえば大幅なページ速度向上が見込まれます。

css・js・画像などをCDNから転送する方法

image_cdn

重いデータをCDN経由で配信することで全体的なページ表示時間の向上が望める。

CDNにも様々な運用方法があります。その中で最も簡単な方法は文書とコンテンツを分けて配信する方法です。

帯域の狭いサーバーでは画像データやjsファイルの転送に時間がかかります。それらの重いファイルだけでもCDNから読み込ませるようにすればページの表示速度を向上させることができます。

この方法はサーバー側での操作が殆どなく、htmlファイルの書き換えや専用プラグインの導入などで対応できるため、導入が非常に簡単であるという利点があります。

ただし、webコンテンツそのものはオリジンサーバーから読みに行く方法のため、オリジンサーバーから配信がなければCDNからの読み込みが始まらないという欠点があります。

Webコンテンツを丸ごとキャッシュさせる方法

全てのデータをCDNから配信方法。大抵の場合CDNの方が強力なバックボーン回線を持つためページ表示速度が速くなる

全てのデータをCDNから配信方法。大抵の場合CDNの方が強力なバックボーン回線を持つためページ表示速度が速くなる

もう1つのCDN運用方法として上げられるのがWebコンテンツを丸ごとCDNから配信する方法です。

配信を全てCDNから行うため、高速なCDNバックボーンの恩恵を受けられる上、サーバーがダウンしても一定期間はCDNからコンテンツが配信されるため対障害性も確保することができます。

この方法ではCDN導入が多少複雑になり、DNSの設定が必要になります。

この方法はWebページを丸ごとキャッシュしてしまうため、頻繁に内容が変わるwebコンテンツの場合更新内容がすぐに反映されないことがあります。

サーバーリソースの負荷に対する解決手段

cpu

CDNの導入は手っ取り早くページ表示速度を向上させるためでもありますが、他にもCDNを導入しなければいけない問題があります。

上図のグラフは本サイトを設置しているさくらインターネットのレンタルサーバーのCPU使用時間を表したものです。これはCPUの使用時間が多いほどサーバーへの負荷が高いことを表しています。

さくらインターネットからの明確なラインというのはありませんが、2時間を超えるいうのは負荷の高い使い方のようです。さくらインターネットの共用サーバーを使っているわけですから、他の共通ユーザーの事を考えると負荷をかけるのは望ましくありません

また、最近ではとあるニュースをきっかけに本サイトへの検索流入が増えるという事もありました(俗にいうプチバズ)。このような前触れもなく発生するアクセス増に備えることも必要になってくると考えられます。

AWS CloudFrontを使ってみる

cloudfront

CDNを提供しているサービスはいくつかあります。今回はその中でもAmazon Web Service(AWS)のCloudFrontを使う事に決めました。

AWS CloudFrontは有料サービスではありますが

この2点を理由に、まずはCloudFrontの無料期間が終わるまでCDNを試用してみることに決めました。

テスト環境でのCloudFront導入

CDN導入は初めての試みである事や、私自身ネットワーク系の知識が乏しい所もあるため、いきなり本番環境でのCDN導入はトラブルが発生して取り返しのつかないことになってしまいそうです。そのため、まずはテスト環境を作って動作確認を行います。

サブドメインでテスト用環境check.voltechno.comを構成して、本番環境に見立ててWordPressを導入します。

このURLを変えることなくCDN経由でコンテンツを配信させることができれば、本番環境でもうまくいくはずです。

どの段階でどの作業を行ったのか確認するため、この段階での構成図を下記に示します。(DNSサーバーの存在は省略)

cdn1

テスト環境の状態。

 


それではCloudFrontを使ったCDNの構築に入ります。

その前に、このままcheck.voltechno.comをCNAMEレコードでCloudFrontに割り当てても、Aレコードで割り当てられているオリジンサーバーへのアクセスが優先されてしまいます(というか重複して意味不明な状態になります)。そのため、オリジンサーバーのアドレスをcheck2.voltechno.comに変更します。

cdn2

CDNとURLが重複しないようにオリジンサーバーのURLを変更する。(WordPressの設定は一切弄らない)

CloudFrontの設定

AWSのアカウントを作ってCloudFrontの設定画面を開きます。

aws-select

AWSはマネジメントコンソールの画面を通じて様々なサービスにアクセスできる。今回はストレージ&コンテンツ配信のリストからCloudFrontを選択する。

aws-select2

CloudFrontの画面を開くと新規作成の画面が開くのでGet Startedボタンを押す。

Origin Settings

 

snapcrab_noname_2016-10-23_16-3-20_no-00

オリジンサーバーの情報を設定します。

Origin Domain Name:オリジナルコンテンツのサーバーアドレス、オリジンのアドレス(check2.voltechno.com)を入れる。IPアドレスの指定は不可らしいです。
Origin Path:ディレクトリの設定。空欄でOK
Origin ID:Origin Domain Nameを入力すると自動入力される
Origin Custom Headers:カスタムヘッダーの付与。空欄でOK

Default Cache Behavior Settings

cdn_no-0004

キャッシュとその他情報を設定します。

Path Pattern:そのまま
Viewer Protocol Policy:HTTP and HTTPS
Allowed HTTP Methods:コメントなどはオリジンサーバーに渡してやらないと反映されないため”GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE”を選択
Cached HTTP Methods:そのまま
Forward Headers:Whitelist (デバイス毎に広告位置やウィジェットの環境ごとに変えてある場合指定しなければいけない)
Whitelist Headers:Cloudfront-Is-Destop-Viewer, Cloudfront-Is-Destop-Mobile,Cloudfront-Is-Destop-Tablet] Object Caching:コンテンツのキャッシュ時間。Use Origin Chache Headersを選ぶとサーバー側の設定が適応される。今回はCloudFront側で設定するため
Minimum TTL:300
Maximum TTL:300
Default TTL:300 (この辺は様子を見ながら調整)
Forward Cookies:Cookieをオリジンサーバーに転送するか。転送しないとAnalyticsが動かないので” All”
Query String Forwarding and Caching:Forward all, cache based on all

Distribution Settings

cdn_no-0005

Price Class:エッジロケーションごとの価格を指定。日本語サイトなら”Use Only US,Canada,Europe and Asia”
AWS WAF Web ACL:None
Alternate Domain Names(CNAMEs):独自ドメインの指定。check.voltechno.comを入力(これでCDNにアクセスされるようになる)
SSL Certificate:そのまま
Supported HTTP Versions:そのまま
Default Root Object:空欄
Logging:ログ機能。今回は使わないので”off”
Enable IPv6:IPv6は使わないのでチェックを外す
Comment:わかりやすいコメントを入れられる
Distribution State:そのまま

Behaviors

基本設定はこれで終わりましたが、このままではWordPressの管理画面などにログインできません。管理画面にアクセスできるよう設定を追記する必要があります。

cdn_no-0007

設定変更を行うCDNのチェックを入れ、Distribution Settingsボタンを押す。

Behaviorsタブを選んでCreate Behaviorを押す。

cdn_no-0010
cdn_no-0011

TTL時間を0にすることにより常にオリジンサーバーを読み込むようになります。

Path Pattern:/wp-admin/*
Viewer Protocol Policy:HTTP and HTTPS
Allowed HTTP Methods:GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
Cached HTTP Methods:そのまま
Forward Headers:None(Improves Caching)
Object Caching:
Minimum TTL:0
Maximum TTL:0
Default TTL:0 
Forward Cookies:” All”
Query String Forwarding and Caching:Forward all, cache based on all


同じようにPath Patternを*.phpに変えて同じものをもう1個登録します

cdn_no-0009

これで管理画面(wp-admin)とphpにアクセスする時は常にオリジンサーバーにアクセスするようになります。

設定完了

StatusがInProgressとなり設定の反映が始まります。完了には大体20~30分ほどかかります。

cdn_no-0013s

StatusがDeployedになるとDomain Name上に記載されているアドレスにアクセスできるようになります。(本記事上ではd1b4b01g7urm8z.cloudfront.netと表示されているものです)

表示されているDomain Nameにアクセスするとサイトが表示されるようになります。キャッシュされたものかオリジンに読みに行っているものかはわかりませんが、とりあえず動いてはいるようです。

あとはDNSを設定してDmain Nameであるd1b4b01g7urm8z.cloudfront.netをCNAMEでcheck.voltechno.comに割り当てて全て完了です。(DNSの反映には最大2日ほどかかる場合もあります、気長に待ちましょう)

下がテスト環境下でのCDN導入完了状態を図式化したものになります。

cdn3

CDNへの導入が完了した状態。check.voltechno.comにアクセスするとキャッシュがあればCDNから配信、CDNにキャッシュがなければcheck2.voltechno.comから配信される。どのような場合でもユーザーはcheck.voltechno.comから常にコンテンツが配信されているように見える

 

 

 

これでユーザーから見たアドレスを変えることなくWordPressをCDN経由のアクセスに変更することが出来ました。同じ手順を踏めば本番環境でもCDNへの移行ができるはずです。

さくらのレンタルサーバーとCloudFrontのページ表示速度を比較してみる

CDNでキャッシュ取得も出来ているようなのでGTmetrixでサイトの表示速度を比較してみます。

まずはオリジンサーバーのcheck2.voltechno.com。

check2

うん、このサイトよりも遥かに読み込み速度は早い。記事も少ないしプラグインもほとんど入れてないWordPressは速いですね。

そして次がCloudFront経由であるcheck.voltechno.comの測定結果。

check

!?? うおぉすごい早いぞコレ。

Page Load Timeが1/5になってる!ここまで早いとは思わなかった!!Amazonのサーバーってスゲェ!!!

そんなわけで予想以上の結果が得られました。本サイトにもCloudFrontを導入すればかなりのサイト表示速度の改善が期待できそうです。というわけで本番環境導入へ

 

 

本番環境でのCloudFront設定、しかし…

08e52cdf6522eafd070571b437159297_m

さて、本番環境でのCDN導入ですが、結論から言うと本サイトでのCloudFront導入は一旦中止することとしました。原因は本サイトのURLがネイキッドドメインだったためです。

CDNとネイキッドドメインは相性が悪い

本サイトのURLはvoltechno.comとしています。このようなアドレスの先端に何もついていない形式のドメインはネイキッドドメインと呼ばれます。(Root DomainやApex Domainとも呼ばれます)

さて、このようなネイキッドドメインの扱いについて、RFC1912では下記のように記されています。

2.4 CNAME レコード
CNAME を指す NS レコードは不正であり、 現在の BIND サーバと悪い具合いに衝突するでしょう。実際、BIND の実装では そのようなレコードは無視され、おそらく不十分な委譲 (lame delegation) をもたらします。

→参考:CNAMEの間違った使い方

つまりどういうことかというとネイキッドドメインはCNAMEレコードで使っちゃいけないよ、問題が起こるよ。だそうです。

実際のところ設定さえできてしまえば特に問題なく動くらしいですが(sendmailで不都合は起こるそうですが)、このドメイン利用を後々どこまで広げるかわからないので、変なことはしないでおきます。

結局CDN導入は一時見送り

今回はドメインの制約に引っかかってしまいCDNの導入は一時見送りとしました。勿論、あくまでも「一時見送り」なので再びCDN導入するつもりです。

この問題に対する最も簡単な解決法としてはアドレス変更が上げられるのですが、問題となるのは本サイトのgoogleサーチコンソールに登録しているURLがhttp://voltechno.com/blog/となっている点です。

Googleサーチコンソールのアドレス変更手続きはディレクトリで登録されたURLには対応していません。アドレスの変更自体は容易ですが、数少ない購読ユーザーに再ブックマークの手間をかけさせることや、検索エンジン評価が初期化されてしまうリスクを考えるとアドレス変更は現実的ではありません。

ですが、色々調べてみると、このネイキッドドメインにCDNを導入する問題については何個か解決方法があるようです。

ネットで見つかった限りでは、「リクエスト全てをサブドメインに転送する設定をウェブサーバーに組み込む」とか、「CDNをCloudflareに変える」とか、「ネームサーバーを別のところに変える」とか、色々と方法はあるようです。次回挑戦して上手くいったら追記報告したいと思います。

 

また、今回のCloudFrontの導入にあたり初めてAWSを使ってみたんですが、すごいですねAWS。

現時点で使用しているウェブサービスはgoogleやさくら・AWSと色々分散してしまっているのですが、ちょっと頑張れば全部AWSでまとめることが出来そうです。しかも、サーバー維持費は今よりも安くなる可能性が…また、AWS IoTも興味深いです(ThingWorxが対応しているのもさらに興味深いです)、もうWebコンテンツのほぼ全てAWSで済んじゃうじゃないですか。

 

さて、今回CDNについていろいろやってみましたが、私自身ネットワークの人間ではなく、本職の方に比べれば遥かにネットワーク系の知識に疎いほうの人間です。この記事の内容にしても「CloudFrontの設定がよくない」とか「CDNの解釈が間違っている」とか「そもそもDNSの理解が乏しい」などがあるかもしれません。ていうかあります

もし何かに気付いたり間違い指摘、参考リンクの提示などがあれば、Contactからアドバイスいただけるとありがたいです。