そのnginxのキャッシュ、ちゃんとpurgeされていますか?

分かる人にしか分からないタイトルにしてみました。ころすけ(@wg_koro)です。

コーディング中

このブログ(WordPress)はnginxとfastcgiで運用しているんですが、設定を見直していると「あれ?」と思うことが。

Cache Purgeプラグインで403

WordPressにはNginx Proxy Cache Purgeというプラグインを入れています。これはエントリーを投稿/編集/削除した時に、特定のURL(nginxのキャッシュを削除するためのURL。デフォルトは「/purge/エントリーパス」)にHTTPアクセスをしてくれるプラグインです。

アクセスログを調べると、この/purge以下のアドレスにアクセスした時に403が返されています。あれれ?本来は200404(キャッシュが存在しない時は404)が返るはず。こりゃあかん。

原因

アクセス許可していなかった。

[shell]
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;

proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
[/shell]

ローカルの127.0.0.1のみアクセス許可していたんですが、ログをよく調べたら、purgeプラグインはサーバー自身のIPアドレスでアクセスしていました。なるほどこれか。

というわけで、サーバー自身のIPを許可するように修正。

[shell]
location ~ /purge(/.*) {
allow 127.0.0.1;
allow xxx.xxx.xxx.xxx;
deny all;

proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
[/shell]

モバイル用のキャッシュはpurgeされていない

よく調べたら、スマートフォンやケータイ向けのキャッシュが削除されていませんでした。

nginxのconfigはあちこちで説明されているものを流用しています。キャッシュ部分はこんな感じ。

[shell]
set $mobile ""

if ($http_user_agent ~* ‘(DoCoMo|J-PHONE|Vodafone|MOT-|UP\.Browser|DDIPOCKET|ASTEL|PDXGW|Palmscape|Xiino|sharp pda browser|WindowsCE|L-mode|WILLCOM|SoftBank|Semulator|Vemulator|J-EMULATOR|emobile|mixi-mobile-converter)’) {
set $mobile 1;
}
if ($http_user_agent ~* ‘(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry|Windows Phone)’) {
set $mobile 2;
}
 :(略)
proxy_cache_key "$scheme://$host$request_uri$is_args$args$mobile";
[/shell]

User Agentで変数$mobileを振り分ける。この変数をキャッシュキーに組み込み、PC、ケータイ、スマートフォンで異なるキャッシュが生成されるようにしてあります。

Purge部分も、他で説明されているものをそのまま使用。

[shell]
location ~ /purge(/.*) {
allow 127.0.0.1;
allow xxx.xxx.xxx.xxx;
deny all;

proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
[/shell]

あれ、これだと変数$mobileは「PC」になるからPC用キャッシュは削除できるけど、ケータイ、スマートフォン用のキャッシュは削除できないんじゃないか?。

確認してみると、PC用キャッシュはクリアされていましたが他のデバイス向けキャッシュは残ったままでした。やっぱり。

結局、こうしてみた

1.各デバイス用のPurge URLを用意する

[shell]
location ~ /purge(/.*) {
allow 127.0.0.1;
allow xxx.xxx.xxx.xxx;
deny all;

proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
# スマートフォンやケータイ用のPurge URLを用意する
location ~ /pg_s(/.*) {
set $mobile 2;
allow 127.0.0.1;
allow xxx.xxx.xxx.xxx;
deny all;

proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
location ~ /pg_f(/.*) {
set $mobile 1;
allow 127.0.0.1;
allow xxx.xxx.xxx.xxx.
deny all;

proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
[/shell]

/purge 以外に、下記2つのURLを用意しました。

  • /pg_s/xxx スマートフォン用キャッシュ削除
  • /pg_f/xxx ケータイ用キャッシュ削除

2.Nginx Proxy Cache Purgeを改造

purgeプラグインが動く時、/purgeだけでなく /purge, /pg_s, /pg_f 3つのURLにアクセスするようにnginx-proxy-cache-purge.phpを改造します。

改造したらエントリーを更新して、アクセスログを確認してみる。
ログ
うん、ちゃんと3つのURLにアクセスされていますね。※pg_fはケータイ用のキャッシュを作っていないので404でOK。

念のため、configにadd_header X-Cache $upstream_cache_status;をセットしてキャッシュステータスも確認してみる。
キャッシュoff
ステータスがMISS(キャッシュが使われていない状態)になっているのでOK。これでエントリー編集・削除時に全デバイスのキャッシュが削除されるようになりました。満足!

今回作ったパッチファイルはコチラ (Gist)

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください