【X-Accel-Expires】Nginxのキャッシュ時間をWordPress側で制御する方法

Nginxのfastcgi_cacheなどのキャッシュ時間を、WordPress側で制御する方法を紹介します。WordPress側で制御することにより、個別記事ページでは1時間キャッシュさせ、アーカイブページでは1日キャッシュさせるなど、ページごとにキャッシュ時間を変更できます。

また、投稿直後は変更の可能性を考えて、キャッシュ時間を短くすることなどができます。例えば、「投稿から1日経過するまでは、キャッシュ時間を1分間にする」などです。

Nginxのキャッシュ周りの設定

Nginxのキャッシュ周りは以下のように設定しておきます。

http {
    ...
    fastcgi_cache_path /var/data/nginx/cache keys_zone=CACHE_ZONE:10m levels=1:2 inactive=6h max_size=1g;
    ...
    server {
        ...
        location ~ \.php$ {
            fastcgi_cache CACHE_ZONE;
            fastcgi_cache_key $scheme$request_method$host$request_uri;
            fastcgi_cache_valid 200 302 5m;
            # 備考の通り必要有りませんが、検証のために追加しています。
            fastcgi_pass_header X-Accel-Expires;
            ...
        }
        ...
    }
}

WordPress側でキャッシュ時間を制御する

WordPress側からNginxのキャッシュ時間を制御するのは、レスポンスヘッダにX-Accel-Expiresを追加するだけです。例えばNginxのキャシュ時間を1時間にするには、使用中のテーマのfunctions.phpに以下のコードを追加します。

function set_expires() {
    // Nginxのキャッシュ時間を3600秒(1時間)にします。
    header('X-Accel-Expires: 3600');
}
add_action('template_redirect', 'set_expires');

ページごとにキャッシュ時間を変更する

上記set_expiresを修正すれば、ページごとにキャッシュ時間を変更することも可能です。以下がそのサンプルコードになります。

function set_expires() {
    if (is_single()) {
        // 個別記事ページは1時間キャッシュさせます。
        header('X-Accel-Expires: 3600');
    } else if (is_archive()) {
        // アーカイブページは1日キャッシュさせます。
        header('X-Accel-Expires: 86400');
    }
}
add_action('template_redirect', 'set_expires');

投稿・更新直後はキャッシュ時間を短くする

最後に、記事の投稿・更新直後はキャシュ時間を短くするサンプルを掲載します。下記例では投稿日、または更新日から1日以内はキャッシュ時間をを1分間としています。そして、それ以降は1時間キャッシュするようにしています。

function set_expires() {
    if (is_single()) {
        $time_delta = time() - get_the_modified_date('U');
        if ($time_delta < 86400) {
            // 更新から1日以内は、1分間キャッシュします。
            header('X-Accel-Expires: 60');
        } else {
            // それ以降は1時間キャッシュします。
            header('X-Accel-Expires: 3600');
        }
    }
}
add_action('template_redirect', 'set_expires');

備考

「fastcgi_pass_header X-Accel-Expires」について

キャッシュ時間を変更するにあたってfastcgi_pass_header X-Accel-Expires;の部分は必要ありません。ただ、この設定を書いておくと検証のときに役立ちます。

なぜならば、ドキュメントの通り、この設定によりクライアントにX-Accel-Expiresを返すようになるからです。つまり、レスポンスヘッダにX-Accel-Expires: xxxが追加されるようになるので、curlコマンドなどを使った検証がやりやすくなります。

$ curl -I https://test.remotestance.com/
HTTP/1.1 200 OK
...
X-Accel-Expires: 3600  <- X-Accel-Expiresが返ってくるので確認がしやすくなります〜
...

キャッシュが効いているかの判別方法

「ほんとにキャッシュ時間を制御できているの??」と感じた場合は、upstreamにあるサーバのアクセスログを見ると判別しやすいです。アクセスログをtail -fで表示し続け、キャッシュを確認するURLを叩いて「アクセスログが更新されなければキャッシュが効いている、更新されればキャッシュが切れている」と判別できます。

tail -f /var/log/php-fpm/latest/access.log
127.0.0.1 -  02/Jun/2015:xx:xx:xx +0900 "GET /index.php" 200 /var/www/test.remotestance.com/index.php 2215147.825 17664 0.71%
↑
アクセスログが更新されたのでキャッシュが切れている!!

この記事が役に立った場合、シェアしていただけると励みになります!!