proxy_cache_purge が思うように動かずドツボに嵌まるの巻

本記事は最終更新日より 1 年以上経過しております。
スポンサーリンク

 先日、ソースビルドへと切り替えるきっかけとなった ngx_cache_purge モジュールの導入により、WordPress からキャッシュを削除する事が出来るようにと作業を行ったのだが、なんだか上手く動いていないようだった。


 ngx_cache_purge モジュールの説明に加えて、PC とモバイル端末ではキャッシュを分けているからキャッシュキー通りになるよう、こちらも $is_mobile と付けるようにしている。https://example.com/purge/ でアクセスすると PC でトップにアクセスした際のキャッシュが削除されるような仕組みに。

    location ~ /purge(\/.*) {
        set $is_mobile 0;
        allow 127.0.0.1;
        allow 192.168.1.0/24;
        deny all;
        proxy_cache_purge czone "$scheme://$host$1$is_args$args$is_mobile";
    }

 キャッシュキー自体の設定は

    location / {
        proxy_pass         http://backend;
        proxy_cache        czone;
        proxy_no_cache     $do_not_cache;
        proxy_cache_bypass $do_not_cache;
        proxy_cache_key    "$scheme://$host$request_uri$is_args$args$is_mobile";
        proxy_set_header   Host                   $host;
        proxy_set_header   X-Real-IP              $remote_addr;
        proxy_set_header   X-Remote-Addr          $remote_addr;
        proxy_set_header   X-Forwarded-Proto      https;
        proxy_set_header   X-Forwarded-Host       $host;
        proxy_set_header   X-Forwarded-Server     $host;
        proxy_set_header   X-Forwarded-For        $proxy_add_x_forwarded_for;
        proxy_cache_valid  200 1d;
    }

 この様になっており $request_uri は location ~ /purge(\/.*) でマッチした部分である $1 に置き換わるから OK なハズ。
 実際、この様な設定でブラウザからアクセスすればキャッシュが生成されて /purge/ にアクセスすれば「Successful purge」と表示されて削除される。
 しかし、WordPress のプラグインで同じ URL を叩くような事をする機能を用いても 404 が返るばかりで削除されない。
 では更にと、curl でローカルから URL へアクセスしても 404 でエラー。でも、curl でいったんトップページへアクセスした後なら削除が可能なのだが、何故か KEY が同じでもキャッシュファイル自体が異なる。
 つまり、Chrome や Firefox 等の Web ブラウザからアクセスされて生成されるキャッシュと、サーバー上で curl 等でアクセスした場合では、生成されるキャッシュの KEY が同じでもキャッシュファイルが異なるので WordPress のプラグインからもキャッシュ制御が出来ていないと言う事に。

 さてさて、何がどう悪いのか今一理解していない。
 必ずこれは乗り越えないと面倒な事になるから、解決したら追って記事にしようと思う。非常に悩ましいorz

2016/01/07 更新

 やっと PC 用としているページに向けたキャッシュの問題が解決した。
 原因としては gzip でコンテンツを圧縮して転送する所にあった。とりあえず gzip を off にして解決。でもそれでは正直こまるので少しずつ追って行った所「gzip_vary on;」にしていた所を off にする事で解決すると分かった。
 しかし、Vary ヘッダが無くなるのもちょっとアレだから、細かい設定の記述や位置などを見なおしていかなければならない。その上、モバイル端末用のキャッシュは変わらず同じ KEY で異なるキャッシュファイルを産むから完全な解決にはほど遠い。
 キャッシュ制御は難しいなと感じた。

2016/01/08 更新

 もっと他の項目まで設定を追って行ったら、バックエンドの記述中に gzip 関連の設定がなかった。
 gzip は http ブロック中に記載するから、バーチャルホスト全てに適用されている。ということは、フロントもバックも両方 gzip で圧縮した転送を行っている事に。
 改めて次の様な gzip の設定を http ブロック中に記述した。

    gzip on;
    gzip_http_version 1.0;
    gzip_vary on;
    gzip_static on;
    gzip_proxied any;
    gzip_comp_level 2;
    gzip_types   text/plain
                 text/xml
                 text/css
                 application/xml
                 application/xhtml+xml
                 application/rss+xml
                 application/atom_xml
                 application/javascript
                 application/x-javascript;
    gzip_disable "MSIE [1-6]\." "Mozilla/4";
    gzip_buffers 16 8k;

 そして ReverseProxy にて 運用しているホストのバックエンドの server ブロックへ次の 2 行を追加した。

    gzip off;
    gzip_vary off;

 これでひとまず Proxy Cache で PC 用のキャッシュが「同じ KEY で異なるキャッシュファイルを産むこと」が無くなった。
 それに伴い、WordPress の記事投稿/更新時に自動で ngx_cache_purge モジュールを用いた purge するプラグインの動作も確認が出来るようになった。
 あとは、モバイル端末に用意している KEY で purge してくれないとか、モバイル端末用キャッシュでは同じ KEY で異なるキャッシュファイルを生成する現象は続いているので原因を探らないと行けない。User-Agent 毎にキャッシュファイルが作られていたらどうしようも無い所だが……

スポンサーリンク