LiveAgent には大量の静的ファイルが含まれており、これらは標準的なWebサーバー(Apacheなど)を使用するよりも、Varnishサービスを利用することではるかに高速に配信できます。同じハードウェア上でApacheと比較した場合、10倍から100倍のパフォーマンス向上が見られることも珍しくありません。Varnishの設定に少し時間をかける価値は十分にあります。静的ファイルの例としては、画像(ロゴ、アイコン)、ライブチャットウィンドウのHTML、JavaScriptファイルなどが挙げられます。

Varnishを導入しても、Apacheの機能を置き換えるわけではありません。Varnishはリクエストを受け取り、キャッシュにファイルが存在しない場合にApacheへリクエストをプロキシする形で、Apacheの前段に配置されます。現在の構成のイメージ:

  • Apacheがポート80で動作し、Webサイトの訪問者にコンテンツを提供している
  • リクエスト例:訪問者のブラウザがexample.jpg(ポート80)にリクエスト <—-> Apache(ポート80)

Varnishを導入した場合の構成:

  • ポート80ではVarnishが待ち受け、Apacheはポート8080などで待ち受けるよう設定する
  • リクエスト例:訪問者のブラウザがexample.jpg(ポート80)にリクエスト <—-> Varnish(ポート80) <—-> Apache(ポート8080)

インストール

  1. Varnishサービスのインストール方法はOSによって異なります。お使いのOSに適した方法でインストールするよう、サーバー管理者にご相談ください。

yumを使用してインストールする場合は、以下のコマンドを実行してください:

yum install epel-release
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.1.el6.rpm
yum install varnish
  1. 設定:

Varnishサービスの設定ファイル(/etc/sysconfig/varnish)の例を以下に示します(ストレージサイズはサーバーのメモリ容量に応じて調整してください):

# Configuration file for Varnish Cache
#
# /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this
# shell script fragment.
#

# Maximum number of open files (for ulimit -n)
NFILES=131072

# Locked shared memory (for ulimit -l)
# Default log size is 82MB + header
MEMLOCK=82000

# Maximum number of threads (for ulimit -u)
NPROCS="unlimited"

# Maximum size of corefile (for ulimit -c). Default in Fedora is 0
# DAEMON_COREFILE_LIMIT="unlimited"

# Init script support to reload/switch vcl without restart.
# To make this work, you need to set the following variables
# explicit: VARNISH_VCL_CONF, VARNISH_ADMIN_LISTEN_ADDRESS,
# VARNISH_ADMIN_LISTEN_PORT, VARNISH_SECRET_FILE.
RELOAD_VCL=1

# Main configuration file.
VARNISH_VCL_CONF=/etc/varnish/default.vcl

#
# Default address and port to bind to
# Blank address means all IPv4 and IPv6 interfaces, otherwise specify
# a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
VARNISH_LISTEN_PORT=80

#
# Telnet admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082

#
# Shared secret file for admin interface
VARNISH_SECRET_FILE=/etc/varnish/secret
#
# The minimum number of worker threads to start
VARNISH_MIN_THREADS=50

#
# The Maximum number of worker threads to start
VARNISH_MAX_THREADS=1000

#
# Cache file size: in bytes, optionally using k / M / G / T suffix.
VARNISH_STORAGE_SIZE=512M

#
# Backend storage specification
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"

#
# Default TTL used when the backend does not specify one
VARNISH_TTL=120

#
# DAEMON_OPTS is used by the init script.
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
             -f ${VARNISH_VCL_CONF} \
             -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
             -p thread_pool_min=${VARNISH_MIN_THREADS} \
             -p thread_pool_max=${VARNISH_MAX_THREADS} \
             -S ${VARNISH_SECRET_FILE} \
             -s ${VARNISH_STORAGE}"

VCL設定ファイル(/etc/varnish/default.vcl)の例は以下のとおりです:

vcl 4.0;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .first_byte_timeout = 600s;
    .connect_timeout = 600s;
    .between_bytes_timeout = 600s;
}

sub vcl_recv {
     set req.backend_hint = default;
      if (req.http.x-forwarded-for) {
        set req.http.X-Forwarded-For = req.http.X-Forwarded-For +",+ "+ client.ip;
     } else {
        set req.http.X-Forwarded-For = client.ip;
     }

     if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|mp4|swf)") {
          # No point in compressing these
          unset req.http.Accept-Encoding;
        } else if (req.http.Accept-Encoding ~ "gzip") {
          set req.http.Accept-Encoding = "gzip";
        } else if (req.http.Accept-Encoding ~ "deflate") {
          set req.http.Accept-Encoding = "deflate";
        } else {
          # unknown algorithm
          unset req.http.Accept-Encoding;
        }
      }

     if (req.method != "GET" &&
       req.method != "HEAD" &&
       req.method != "PUT" &&
       req.method != "POST" &&
       req.method != "TRACE" &&
       req.method != "OPTIONS" &&
       req.method != "DELETE") {
         /* Non-RFC2616 or CONNECT which is weird. */
         return (pipe);
     }

     if (req.url ~ "M\=readBus") {
         return (pipe);
     }
     if (req.method != "GET" && req.method != "HEAD") {
         /* We only deal with GET and HEAD by default */
         return (pass);
     }

     if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|mp4|swf|html|js|css|zip|pdf)") {
        unset req.http.Cookie;
     }
     if (req.url ~ "cache/bus/.*\.js") {
        return (pass);
     }
     return (hash);
}

 sub vcl_pipe {
     set req.http.connection = "close";
     set bereq.http.connection = "close";
     return (pipe);
 }

  sub vcl_pass {
     return (fetch);
 }

 sub vcl_backend_response {
    unset beresp.http.X-Varnish;
    if (beresp.ttl < 2m) {
       set beresp.grace = 5m;
    } else {
       set beresp.grace = 15s;
    }

    if (beresp.http.content-type ~ "(text|javascript)") {
      set beresp.do_gzip = true;
    }

    if (beresp.ttl > 14400s) {
      set beresp.ttl=14400s;
    }

    # These status codes should always pass through and never cache.
    if (beresp.status >= 400 || !(beresp.ttl > 0s) || beresp.http.Cache-Control ~ "(private|no-cache|no-store)") {

       set beresp.ttl=0s;
       set beresp.uncacheable = true;
       return (deliver);
    }

    if (bereq.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|mp4|swf|html|js|css|zip|pdf)") {
       unset beresp.http.set-cookie;
    }
    return (deliver);
}

sub vcl_deliver {
   set resp.http.Vary= "Accept-Encoding";
   set resp.http.Via= "1.1 varnish (1.lb-app.la.linode-sg)";
}

sub vcl_miss {
    return (fetch);
}

sub vcl_backend_error {
    set beresp.http.Content-Type = "text/html; charset=utf-8";
    set beresp.http.Retry-After = "60";
    synthetic( {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <title>"} + beresp.status + " " + beresp.reason + {"</title>
  </head>
  <body>
    <h1>Error "} + beresp.status + " " + beresp.reason + {"</h1>
    <p>"} + beresp.reason + {"</p>
    <h3>Guru Meditation:</h3>
    <p>XID: "} + bereq.xid + {"</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>"} );
    return (deliver);
}
  1. Apacheの設定ファイルで、Apacheが待ち受けるポートを80から8080に変更してください。

  2. Apacheを再起動し、その後Varnishサービスを起動してください。