varnish

WordPress サイトに Varnish を導入する

varnishWordPress サイトにリバースプロキシサーバ Varnish を導入する際の tips。
リバースプロキシって何?って人は、以下のURL辺りを参考にしてください。
Insider's Computer Dictionary [リバースProxy] − @IT

通常は複数台あるバックエンドのサーバを取りまとめるロードバランサー的な使われ方をします。
しかし、一台しかサーバが無い場合でも、フロントにリバースプロキシを置いてリクエストを受けて、バックエンドで動作している Web サーバから受け取った動的コンテンツをキャッシュさせて負荷を軽減させることもできます。
この構成を取っておけば、負荷が増えてサーバがきつくなったときに、わりと手軽にアプリケーションサーバを分離できますね。
# 個人ブログで、そこまで行くとは思いませんが

Varnish のインストール方法とか、基本的な設定は以下のサイトが参考になりますよ。

ここでは、WordPress サイトにリバースプロキシとして Varnish を導入する際の tips をいくつか紹介します。

ログイン時以外は cookie を処理しない

通常の WordPress サイトでは、ログイン時以外も Cookie が送信されます。
それにより Varnish は上手に動的コンテンツをキャッシュできなくなる可能性があります。
以下のような設定を追加することで、ログイン時以外は Cookie を送信しないようにすることができます。

sub vcl_recv {
  # ...
  # admin users always miss the cache
  if( req.url ~ "^/wp-(login|admin)" || req.http.Cookie ~ "wordpress_logged_in_" ){
    return (pass);
  }
  # ignore any other cookies
  unset req.http.Cookie;
  return (lookup);
}

via. Varnish with PHP (and WordPress) | timwhitlock.info

不要な HTTP ヘッダやパラメータを剥ぎ取ってキャッシュしやすくしよう

ブラウザから受信した HTTP ヘッダやパラメータの違いにより、同じファイルにアクセスしているのに、別のキャッシュができてしまう可能性があります。
例えば、gzip 圧縮転送に対応していないブラウザからのリクエストと、対応しているブラウザからのリクエストでは Accept-Encoding という、HTTP ヘッダの内容が異なってきます。
画像ファイルなどのバイナリファイルは html や、JS、CSS などのテキストファイルと違い、gzip 圧縮転送はされないので Accept-Encoding ヘッダは無視して同じファイルをキャッシュしておいて、ブラウザに返せば良さそうです。
以下のような設定を追記することで、これらの不要な HTTP ヘッダや Cookie を削除してくれます。

sub vcl_recv {
# Normalize Content-Encoding
    if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|lzma|tbz)(\?.*|)$") {
            remove req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        } else {
            remove req.http.Accept-Encoding;
        }
    }
# Remove cookies and query string for real static files
    if (req.url ~ "^/[^?]+\.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)(\?.*|)$") {
       unset req.http.cookie;
       set req.url = regsub(req.url, "\?.*$", "");
    }
# Remove cookies from front page
    if (req.url ~ "^/$") {
       unset req.http.cookie;
    }
}

via. My Varnish VCL for WordPress | Mudy's Blog

キャッシュされやすいように HTTP ヘッダを出力する

キャッシュされやすいように短い間隔でいいので Expires ヘッダを出力するようにしてあげましょう。
これにより、アクセスが短い時間に集中した場合でも、毎回アプリケーションサーバと通信せず、リバースプロキシサーバ上にキャッシュされた出力を返すようになります。
via. Varnish を使って PHP アプリケーションのスケーリングを行う

例えば、以下のようなコードをテーマの functions.php に追加しておくだけで、ログオンしているとき以外は 10秒間の Expires ヘッダが出力されます。
ただし、このままだと Ktai Style 等で、モバイルからのアクセス時に違う結果を返している場合は、不具合が発生するかもしれません。

Class cache_manager {
  static public function to_gmt( $now = null ) {
    return gmdate( 'D, d M Y H:i:s', ( $now == null ) ? time() : $now );
  }
  static public function last( $time = null ) {
    $gmt = self::to_gmt( $time );
    header("Last Modified: $gmt");
  }
  static public function expires( $expire ) {
    $gmt = self::to_gmt( time() + $expire );
    header("Expires: $gmt");
  }
  static public function cache_control( $options ) {
    header("Cache-Control: $options");
  }
}
function cache_control(){
  if (!is_user_logged_in()) {
    cache_manager::cache_control( "public,max-age=10");
    cache_manager::expires(10);
    cache_manager::last();
  }
}
add_action('init', 'cache_control');

まとめ

リバースプロキシ Varnish を導入すると、わりとお手軽にサーバの負荷軽減できるので、大規模案件とかでは試してみる価値ありますよー。というお話でした。
ただし、このサイトでは Varnish ではなく nginx をリバースプロキシとして使ってます。
次回は、その辺の解説をしますね。

1 thought on “WordPress サイトに Varnish を導入する

  1. ピンバック: Tweets that mention WordPress サイトに Varnish を導入する : dogmap.jp -- Topsy.com

コメントを残す

メールアドレスが公開されることはありません。

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