LoginSignup
47
47

More than 5 years have passed since last update.

CDN化をnginxの設定で行う方法

Last updated at Posted at 2014-08-27

瞬間的な高負荷に耐える為にアプリケーション側を変更せず、nginxの設定のみで対応する方法

CDNとは、「Contents Delivery Network」といわれるもので、最適なネットワークを経由してWebコンテンツをキャッシュし効率的に配信できる物です。Amazon(AWS)では「CloudFront」というサービスがあります。他にも「Akamai」などが有名です。

前提条件

  • バックエンドにProxyするCMSを使う(ここではPlone) (画像等も静的なデータではなくCMSから配信)

今回の実験

  • CDNには、Amazon(AWS) CloudFrontを用いた
  • nginx - Varnish - CMSアプリ(Plone(複数台))という構成(当社が普段から使っている構成)
  • 画像やファイルなどのみをCDNから配信させる
  • 画像やファイルのオリジナルは、Plone内つまり、同じnginxからCDNに転送

手順

  • CDN(Amazon CloudFront)を設定する。 Web用、HTTP/HTTPSを使う、Custom Originの設定を行う。(下部の「参考にしたサイト(1)」を参照)
  • nginxの設定を行う

ポイント

方式

  • nginxにて指定のURI(画像などを特定)は、CDN(CloudFront)にリダイレクトする
  • 指定のURIは、正規表現を用いて、Ploneの仕様に合わせて特定する(これはVarnishのキャッシュ設定と同じ設定を持ってきた) VarnishのサンプルVCLはこちら

nginxのconf

  • locationの中で、proxy_passが1回しか指定できない
  • 複数の条件を分岐できない且つネスト出来ない <これは一番ハマった。(下部の「参考にしたサイト(3)」を参照)
  • Amazon CloudFrontからデータを取得する時は、Ploneからデータを取得出来るようにする (下部の「参考にしたサイト(2)」を参照)

設定ファイルの抜粋

nginx.conf
upstream to_varnish {
    server 127.0.0.1:6081;
}
server {
...
省略
...
    location / {
        if ($uri ~* \.(jpe?g|png|gif|pdf|gz|tgz|bz2|tbz|zip|tiff|tif)$) {
            set $no_plone A;
        }
        if ($uri ~* /(image|(image_(?:[^/]|(?!view.*).+)))$) {
            set $no_plone A;
        }
        if ($uri ~* \.(svg|swf|ico|mp3|mp4|m4a|ogg|mov|avi|wmv|flv)$) {
            set $no_plone A;
        }
        if ($uri ~* \.(css|js)$) {
            set $no_plone A;
        }
        if ( $http_user_agent != "Amazon CloudFront" ) {
            set $no_plone "${no_plone}B";
        }
        if ($no_plone = AB) {
            expires 1h;
            rewrite ^ http://YOUR_SUBDOMAIN.cloudfront.net$request_uri? last;
        }
        proxy_pass http://to_varnish/VirtualHostBase/http/YOUR_DOMAIN:80/Plone/VirtualHostRoot/;
    }

動作確認

  • nginxのログを閲覧 Amazon CloudFront からのアクセスがあることを確認
  • Firebugなどでネットワークの取得元を確認 画像などが、302でCDNへリダイレクトされていて、取得元URLが変わっていた

効果

数人でアクセスしているレベルだと、Varnishで十分はさばけるので、効果を感じることが出来なかった。
(リダイレクトが発生する分、100ms程度時間が掛かるケースもあった)
実際に高負荷状態を作り、Varnishでも耐えられない程度の状態でないと、実感できないと思う。

参考にしたサイト

  1. Amazon CloudFrontをカスタムオリジンで使用する方法
  2. NginxでCloudFrontにリダイレクトしてカスタムオリジンで負荷分散する
  3. Nginxで複数条件のIF文を書く方法がすごいw

著者関連Blog記事

Ploneへの急激なアクセスを処理する方策(CDN化)

47
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
47
47