menu
Webを活用してお客様のビジネス課題を解決します。札幌・東京を拠点にWebコンサルティングをコアにした、Web制作・システム開発・サーバ構築会社です。

ケーススタディ:本番挙動を変えずに静的リソースだけに CDN を適用した事例

シェア
ツイート
シェア
ブックマーク
タイトルとURLをコピー

公開日:2025/05/07

はじめに

あるウェブサイトの運用中、1画面に当初の想定を大幅に超える数の画像を表示する仕様が追加されました。これらの画像はリクエスト時にnginxで動的にサイズ調整される仕組みになっており、実際に本番で動作をさせたところ、今回のケースでは予想以上に画像生成と配信の負荷が高くなることがわかりました。 

この課題に対処するため、該当部分である画像配信部分だけにでもCDNを適用してサーバーの負荷を減らしたいと考えました。 幸い、処理の明確化を意識して適切なパス設計が行われていたため、技術的にはリソースを分離できる状態でした。

しかし、既に稼働している本番サイトのドメイン全体にいきなりCDNを適用するのはリスクが高いと判断しました。テスト環境で十分な検証を行う時間が確保できず、本番環境で予期せぬ問題が発生する可能性を否定できなかったためです。

そこで、影響範囲を最小限に抑えつつ効果を得る方法として特定の静的リソースだけをCDN経由にする構成を提案・選択しました。 この作業はインフラ作業者の担当範疇のみで実施しました。 結果として、本番全体の挙動を変えず、既存のアプリケーションに手を加えることなく、限定的な範囲で負荷軽減を実現できました。

この記事では、具体的にどのように構成を組み、この方法を実現したのかについて解説します。

assets ドメイン向け CDN の設定

まず、以下のような処理を行うことで一部分のみのリソースを別ドメインの CDN 経由でも取得することができる対応を行います。

  • nginxにCDN配信用の server 設定を作成し、本番アプリのnginx設定と同様の server 設定を用意します。この時、assets 経由で公開しても良いファイルのみを取得できるようにしています。
  • nginx の設定後、CDN用の別ドメイン (例えば assets.example.com)でCDNを有効化します。

このようにCDNを準備することで、アプリの正式URL(www.example.com/images/)とassetsドメイン(assets.example.com/images/)の両方で、同じ静的コンテンツを取得できるようになります。ただし、前者からアクセスした場合はコンテンツがサーバーから直接返され、後者からアクセスした場合はCDN経由で、必要に応じてキャッシュされたコンテンツが返されます。

ここで重要なのは、同じパスであればキャッシュの有無に関わらずどちらのドメインを利用しても同じコンテンツを取得できるという点です。

nginx の sub_filter による書き換え

nginxのsub_filter機能を利用すると、レスポンスのHTML内の文字列を動的に置き換えることができます。今回のウェブアプリケーションでは、画像のsrc属性にドメインまで含めたURLが出力される仕様だったため、以下のようなsub_filterを適用しました。

sub_filter “//www.example.com/image/” “//assets.example.com/image/”;

このsub_filterを適用することで、レスポンスとして返されるHTML内のURLが置き換えられます。これにより、HTMLファイルを受け取ったクライアントは、画像の取得先として元のアプリケーションドメインではなく、CDNを適用したドメインにアクセスするようになります。

この仕組みによって、アプリケーション側のコードに手を加えることなく、クライアントのリクエストをCDN経由に誘導することが可能になりました。

この構成を利用するメリット

今回提案した方法にはいくつかのメリットがあります。

  • アプリケーションの改修が不要であるため、開発チームの工数やテスト工数を追加で必要とせず、インフラ担当者の作業だけで対応が完結します。
  • 本番環境のインフラ構成自体を大きく変更しないため、予期せぬ問題が発生するリスクが低く、既存のシステムへの影響を最小限に抑えることができます。
  • インフラ側の設定を戻すだけで切り戻しが完了するため、比較的短時間で復旧が可能です。

このように、「アプリ改修なし」「既存インフラに大きく手を加えない」「万が一の場合の切り戻しが容易」という特性は、本番環境でのリスク管理や工数削減の観点から大きな利点となります。

まとめ

今回の記事は「ケーススタディ」と題しましたが、実際にこの構成変更を行い、負荷を十分に下げることに成功しました。

CDNはキャッシュ機能だけでなく、WAFなどの機能も提供してくれますが、一方で本来キャッシュしてはいけないデータをキャッシュしてしまう事故が発生するリスクもあります。 そのため、サイト全体にCDNを有効化する場合には、利用するCDNの性質を十分に理解した上での運用が必要だと考えています。

今回のアーキテクチャでは、サイト全体ではなく「キャッシュしても良いものだけ」をnginxで判断して返し、それをCDNにキャッシュさせる方式を採用しました。 この構成によって、先述したような事故がほとんど発生しないという点も私がこの方法を気に入っている理由の一つです。

後付けでCDNを利用する場合や、最初から静的リソースを別ドメインに分離する場合など、今回紹介したメリットを魅力に感じた方は、ぜひこの事例を参考にしてみてください。