問題
匿名でWebサイトにアクセスすると、Varnishがページをキャッシュしています。
「匿名ユーザーのキャッシュページ」をオンにしているので、これは予想どおりです。
しかし、ログインすると、ログアウトしたときにアクセスしたページのキャッシュページが引き続き読み込まれるため、ユーザー固有のメニューが表示されず、ログインしているにもかかわらずログインボタンが表示され続けます。
ログインしたユーザーに対してVarnishが機能せず、デフォルトのdrupalキャッシュシステムを使用していますが、ログインしたユーザーに対しては機能しないと思いますが、これを防ぐにはどうすればよいですか?
サーバーのセットアップ
LEMPスタック-Ubuntu Server 12.04
APC + Memcached
ワニス
Drupalキャッシュ設定:
匿名ユーザーのキャッシュページ->有効
最小キャッシュ寿命-> 0
キャッシュページの有効期限-> 6時間
ワニスモジュール設定:
ワニスキャッシュのクリア:Drupal default
このガイドとこのVarnish構成ファイルを使用してVarnishをインストールしました: http://andrewdunkle.com/how-install-varnish-drupal-7
ブラウザキャッシュ
Firefoxでブラウザのキャッシュを無効にしても、ホームページにVarnishのキャッシュヒットが表示されますが、メニューが正しく読み込まれるようになりました。これはどういう意味ですか?
次の2つのオプションがあります。
解決策1:ブラウザーでのキャッシュを許可しない
ブラウザによるページの保存と再利用を防止するには、Cache-Control:no-cache, must-revalidate, post-check=0, pre-check=0
がそれぞれの(HTML)ページにあることを確認する必要があります。
このヘッダーはsub vcl_deliver
で強制できます。そのヘッダーを静的アセット(画像、CSS、JavaScriptファイルなど)に配置しないようにしてください。
sub vcl_deliver {
set req.http.Cache-Control = "no-cache, must-revalidate, post-check=0, pre-check=0";
}
解決策2:変化することを確認する:Cookieが応答にある
Cookieが変更されたとき(セッションが開かれたときなど)にブラウザにキャッシュを無効にさせる場合は、Vary: Cookie
ヘッダーが応答に含まれていることを確認する必要があります。
sub vcl_deliver {
if (resp.http.Vary !~ "Cookie") {
set resp.http.Vary = resp.http.Vary + ", Cookie";
set resp.http.Vary = regsub(resp.http.Vary, "^,\s*", "");
}
}
この場合も、ユーザーがログインしているかどうかによって内容が異なるページ/ファイルタイプをこのフラグメントに制限すると、キャッシュはより効果的です。
Safari(Windowsの最後のバージョンであり、iPad 1と一部の古いiPhoneのバージョンである少なくともv5)には、厄介な bug があります。 Safariブラウザーのキャッシュを非アクティブにするために、以下を省略して追加することをお勧めします。
sub vcl_deliver {
if (resp.http.X-Generator ~ "Drupal" && req.http.user-agent ~ "Safari" && req.http.user-agent !~ "Chrome") {
set resp.http.Cache-Control = "no-cache, must-revalidate, post-check=0, pre-check=0";
}
}
注:これは、バグレポートのコメントで提案されているソリューションとは少し異なります。切り詰めたものをvcl_deliver
ではなくvcl_fetch
に配置することで、ビンを分離する必要がなくなります。また、X-Generator ~ "Drupal"
で照合することにより、静的アセットのブラウザキャッシュを無効にすることを回避できます。
今日(2013年11月)、私はSafari 5.1.1(Windows)、6.1(Mac OS X 10.8/Mountain Lion)および7.0(iOS 7)でこの問題を再現しました。
2番目のオプションを使用することを選択します。スニペットをVanish構成ファイルに追加しました。
/etc/varnish/default.vcl
既存のsub vcl_deliver
内にif関数を配置するのではなく、独自のスタンドアロンスニペットとして追加しました。