Nginxによる自作CDNサーバーの構築:キャッシュ機能とミラーリングの設定

1. ngx_cache_purgeモジュールの組み込み

Nginxのキャッシュ機能を最大限に活用し、特定のキャッシュを手動で削除できるようにするには、ngx_cache_purgeモジュールが必要です。まず、現在のNginxにこのモジュールが含まれているか確認します。

nginx -V

出力結果にngx_cache_purgeが含まれていない場合は、以下の手順でソースから再ビルドを行います。

# 作業ディレクトリへ移動
cd /usr/local/src

# ngx_cache_purgeのダウンロードと解凍
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
tar -zxvf ngx_cache_purge-2.3.tar.gz

# Nginxソースの取得(既存のバージョンに合わせる)
# 例: nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0

# コンパイル設定
# nginx -V で表示された既存の引数に --add-module=../ngx_cache_purge-2.3 を追加
./configure --prefix=/etc/nginx --user=nginx --group=nginx \
--with-http_ssl_module --with-http_v2_module \
--add-module=../ngx_cache_purge-2.3

make
# 既存のバイナリをバックアップしてから差し替え
cp objs/nginx /usr/sbin/nginx

2. proxy_cacheによるキャッシュサーバーの設定

キャッシュサーバーとして動作させるには、まず共有メモリ領域とキャッシュの保存パスを定義します。nginx.confhttpブロックに以下の設定を追加します。

# キャッシュ設定の定義
proxy_cache_path /var/cache/nginx/cdn_cache levels=1:2 keys_zone=static_cache:500m inactive=7d max_size=20g;
proxy_temp_path /var/cache/nginx/temp;

# タイムアウトとバッファの設定
proxy_connect_timeout 10;
proxy_read_timeout 60;
proxy_send_timeout 10;
proxy_buffer_size 32k;
proxy_buffers 4 128k;

次に、仮想ホスト(Serverブロック)でリバースプロキシとキャッシュの挙動を設定します。

server {
    listen 80;
    server_name cdn.example.com;

    location / {
        # オリジンサーバーの指定
        proxy_pass https://origin.example.com;
        proxy_set_header Host origin.example.com;
        proxy_set_header X-Real-IP $remote_addr;
        
        # キャッシュの有効化
        proxy_cache static_cache;
        proxy_cache_valid 200 304 12h;
        proxy_cache_valid 301 1d;
        proxy_cache_valid any 1m;

        # キャッシュステータスをヘッダーに付与
        add_header X-Cache-Status $upstream_cache_status;
        
        # ブラウザキャッシュの制御
        expires 30d;
        add_header Cache-Control "public";
    }
}

3. proxy_storeによるミラーリングサーバーの構築

proxy_storeを使用すると、オリジンから取得したファイルをそのままローカルディスクに保存し、次回以降はNginxが直接静的ファイルとして配信します。これは画像のミラーリングに最適です。

location /images/ {
    root /data/www/cdn_root;
    proxy_store on;
    proxy_store_access user:rw group:rw all:r;
    proxy_temp_path /data/www/cdn_root/temp;

    # ファイルが存在しない場合のみオリジンへリクエスト
    if (!-e $request_filename) {
        proxy_pass https://origin.example.com;
    }
}

4. proxy_cacheとproxy_storeの比較

  • proxy_cache: キー(URL等)に基づいた管理。有効期限(TTL)による自動更新が可能で、動的なコンテンツや大規模なキャッシュに適しています。
  • proxy_store: ディレクトリ構造をそのままミラーリング。一度取得すると自動では更新されないため、静的な画像素材などの配信に適しており、オリジンサーバーの負荷を大幅に削減できます。

5. 運用上の最適化とセキュリティ

検索エンジン対策(robots.txt)

CDNサーバーがオリジンのコンテンツを複製していると見なされないよう、画像以外のクロールを拒否する設定を推奨します。

User-agent: *
Allow: /wp-content/uploads/*.jpg
Allow: /wp-content/uploads/*.png
Allow: /wp-content/uploads/*.gif
Disallow: /

直リンク防止(Hotlink Protection)

CDNの帯域を無駄に消費されないよう、リファラチェックを行います。

location ~* \.(jpg|jpeg|png|gif|webp)$ {
    valid_referers none blocked example.com *.example.com;
    if ($invalid_referer) {
        return 403;
    }
}

オリジン欠損時のフォールバック画像

オリジンに画像が存在しない場合、デフォルトのプレースホルダー画像を表示させることができます。

location /assets/avatars/ {
    try_files $uri /assets/default-avatar.png;
}

タグ: nginx CDN ReverseProxy proxy_cache ServerOptimization

8月5日 15:20 投稿