본문 바로가기

Linux

Varnish 설치 하기

대상 CentOS 6.x


yum으로 기본설치를 하면 2.x의 오래된 버전이 깔려서 repo를 추가 해서 최신 4.1로 설치한다.


rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.1.el6.rpm


참고) CentOS 7은 아래 el7 사용.

rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.1.el7.rpm


다음 yum으로 설치한다.

yum install -y varnish


varnish는 캐시 저장소를 메모리 또는 디스크 (또는 섞어서 여러개도 가능)를 쓰는데.
v4.1은 기본이 메모리 256MB 이다.  이 부분을 시스템 사양에 맞게 (여기선 2GB로) 바꿔준다.


vim /etc/sysconfig/varnish

여기서 아래 부분을 찾아서 256M 을 2G로 바꿔준다.

VARNISH_STORAGE_SIZE=256M


서비스 포트를 80으로 바꿔준다.

VARNISH_LISTEN_PORT=80

ipv6를 지원하지 않는 서버에서는 VARNISH_LISTEN_ADDRESS을 0.0.0.0으로 추가 해준다.

VARNISH_LISTEN_ADDRESS=0.0.0.0


이부분을 안하면 아래 같은 에러가 뜬다.

Starting Varnish Cache: Error: Cannot open socket: :80: Address family not supported by protocol






실제 백엔드랑 동작 설정은 /etc/varnish/default.vcl 에서 한다.
http://book.varnish-software.com/4.0/chapters/VCL_Basics.html 참고 해서 설정해보자..


vim /etc/varnish/default.vcl


vcl 4.0;


import directors;

import std;


backend sitea {

  .host = "xxx.xx.xxx.105";

  .port = "8080";

}

backend siteb {

  .host = "xxx.xx.xxx.104";

  .port = "8080";

}


acl purge {

  "localhost";

  "127.0.0.1";

}

# Define the director that determines how to distribute incoming requests.

sub vcl_init {

  new bar = directors.fallback();

  bar.add_backend(sitea);

  bar.add_backend(siteb);

}


sub vcl_recv {

  set req.backend_hint = bar.backend();


  set req.http.grace = "none";


  # Do not cache these paths.

  if (req.url ~ "^/status\.php$" ||

      req.url ~ "^/admin" ||

      req.url ~ "^/.*\.jsp$" ||

      req.url ~ "^.*/ajax/.*$" ||

      req.url ~ "^.*/ahah/.*$") {


    return (pass);

  }


  if (req.url ~ "(?i)\.(pdf|cab|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") {

    unset req.http.Cookie;

  }



  if (req.http.Cookie) {

    # 1. Append a semi-colon to the front of the cookie string.

    # 2. Remove all spaces that appear after semi-colons.

    # 3. Match the cookies we want to keep, adding the space we removed

    #    previously back. (\1) is first matching group in the regsuball.

    # 4. Remove all other cookies, identifying them by the fact that they have

    #    no space after the preceding semi-colon.

    # 5. Remove all spaces and semi-colons from the beginning and end of the

    #    cookie string.

    set req.http.Cookie = ";" + req.http.Cookie;

    set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");

    set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; \1=");

    set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");

    set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");


    if (req.http.Cookie == "") {

      # If there are no remaining cookies, remove the cookie header. If there

      # aren't any cookie headers, Varnish's default behavior will be to cache

      # the page.

      unset req.http.Cookie;

    }

    else {

      # If there is any cookies left (a session or NO_CACHE cookie), do not

      # cache the page. Pass it on to Apache directly.

      return (pass);

    }

  }

  # Check the incoming request type is "PURGE", not "GET" or "POST".

  if (req.method == "PURGE") {

    # Check if the IP is allowed.

    if (!client.ip ~ purge) {

      # Return error code 405 (Forbidden) when not.

      return (synth(405, "Not allowed."));

    }

    return (purge);

  }

}


sub vcl_deliver {

  set resp.http.grace = req.http.grace;


  if (obj.hits > 0) {

    set resp.http.X-Varnish-Cache = "HIT";

  }

  else {

    set resp.http.X-Varnish-Cache = "MISS";

  }

}


sub vcl_hit {

    if (obj.ttl >= 0s) {

        # normal hit

        return (deliver);

    }

    # We have no fresh fish. Lets look at the stale ones.

    if (std.healthy(req.backend_hint)) {

        # Backend is healthy. Limit age to 10s.

        if (obj.ttl + 10s > 0s) {

            set req.http.grace = "normal(limited)";

            return (deliver);

        } else {

            # No candidate for grace. Fetch a fresh object.

            return(fetch);

        }

    } else {

        # backend is sick - use full grace

        if (obj.ttl + obj.grace > 0s) {

            set req.http.grace = "full";

            return (deliver);

        } else {

            # no graced object.

            return (fetch);

        }

    }

}


sub vcl_backend_response {

    set beresp.ttl = 10s;

    set beresp.grace = 1h;

}