Varnish Cache 4.1 Kurulumu ve WordPress Ayarları

Varnish Cache web sunucunuz önünde çalışarak, önbelleğine aldığı dosyaları/sayfaları, bir daha web sunucunuza istek yapmadan kendi üzerinden kullanıcıya sunan bir önbellekleme sistemidir. Varnish cache hali hazırda kullanılan her türlü web sunucsu ile sorunsu olarak çalışan bir açık kaynak kodlu yazılımdır.

Varnish statik dosyalarınızı (html, css, jpg,png) önbelleklediği gibi, özellikle WordPress gibi dinamik içeriğe sahip sitelerinizi de önbellekleme kabiliyetine sahiptir. Asıl amacı sunucu kaynaklarını en verimli şekilde kullanmaya yöneliktir.

Yaptığım  denemeler sonucu WordPress için en uygun ayarları Varnish 3.x sürümü ile elde ettim. Bu yazımda sizlere Varnish 3.x kurulumu ve WordPress için VCL ayarlarından bahsedeceğim.

Varnish 4.1 Kurulumu

Red Hat Enterprise Linux 7, Red Hat Enterprise Linux 6, Debian 8 64 bit ve Ubuntu 14.04 64 bit için ayrı ayrı kurulum ve depo kaynakları olsa da, tüm ayarlamalar tüm işletim sistemleri için ortaktır.

Öncelikle kullandığınız işletim sistemine uygun olan paketi seçtiğinizdem emin olunuz.

Red Hat Enterprise Linux 7

yum install epel-release
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.1.el7.rpm
yum install varnish

Red Hat Enterprise Linux 6

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

Debian ve Ubuntu için /etc/apt/sources.list dosyasını düzenleyerek uygun olan repo kodunu en sona ekleyin.

deb http://repo.varnish-cache.org/debian/ wheezy varnish-3.0

Debian 8.x 64 bit

deb https://repo.varnish-cache.org/debian/ jessie varnish-4.1

Ubuntu 14.04 64 bit

deb https://repo.varnish-cache.org/ubuntu/ trusty varnish-4.1

Debian ve Ubuntu için depo anahtarını ekleyip, depo listesini güncelleyip kurulumu yapalım.

curl https://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add -
apt-get update
apt-get install apt-transport-https varnish -y

Kurulum tamanlandığında aşağıdaki gibi bir mesaj göreceksiniz.

Unpacking varnish (4.1.0-1~trusty) ...
Processing triggers for ureadahead (0.100.0-16) ...
Processing triggers for man-db (2.6.7.1-1ubuntu1) ...
Setting up libvarnishapi1 (4.1.0-1~trusty) ...
Setting up varnish (4.1.0-1~trusty) ...
 * Starting HTTP accelerator varnishd                                    [ OK ]
Processing triggers for libc-bin (2.19-0ubuntu6.6) ...
Processing triggers for ureadahead (0.100.0-16) ...
[email protected]:/etc/apt#

Varnish default ve default.vcl ayarları

default dosyamızı düzenleyelim.

Debian ve Ubuntu için

nano /etc/default/varnish

CentOS için

nano /etc/sysconfig/varnish

İçerğini aşağıdaki gibi değiştirelim.

# Configuration file for varnish
#
# /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK
# to be set from this shell script fragment.
#
# Note: If systemd is installed, this file is obsolete and ignored.  You will
# need to copy /lib/systemd/system/varnish.service to /etc/systemd/system/ and
# edit that file.

# Should we start varnishd at boot?  Set to "no" to disable.
START=yes

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

# Maximum locked memory size (for ulimit -l)
# Used for locking the shared memory log in memory.  If you increase log size,
# you need to increase this number as well
MEMLOCK=82000

# Default varnish instance name is the local nodename.  Can be overridden with
# the -n switch, to have more instances on a single server.
# INSTANCE=$(uname -n)

# This file contains 4 alternatives, please use only one.

## Alternative 1, Minimal configuration, no VCL
#
# Listen on port 6081, administration on localhost:6082, and forward to
# content server on localhost:8080.  Use a 1GB fixed-size cache file.
#
# DAEMON_OPTS="-a :6081 \
#              -T localhost:6082 \
#              -b localhost:8080 \
#              -u varnish -g varnish \
#              -S /etc/varnish/secret \
#              -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"


## Alternative 2, Configuration with VCL
#
# Listen on port 6081, administration on localhost:6082, and forward to
# one content server selected by the vcl file, based on the request.
# Use a 256MB memory based cache.
#
DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"


## Alternative 3, Advanced configuration
#
# See varnishd(1) for more information.
#
# # Main configuration file. You probably want to change it 🙂
# 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_ADDRESS=
# VARNISH_LISTEN_PORT=6081
#
# # Telnet admin interface listen address and port
# VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
# VARNISH_ADMIN_LISTEN_PORT=6082
#
# # The minimum number of worker threads to start
# VARNISH_MIN_THREADS=1
#
# # The Maximum number of worker threads to start
# VARNISH_MAX_THREADS=1000
#
# # Idle timeout for worker threads
# VARNISH_THREAD_TIMEOUT=120
#
# # Cache file location
# VARNISH_STORAGE_FILE=/var/lib/varnish/$INSTANCE/varnish_storage.bin
#
# # Cache file size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
# VARNISH_STORAGE_SIZE=1G
#
# # File containing administration secret
# VARNISH_SECRET_FILE=/etc/varnish/secret
#
# # Backend storage specification
# VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
#
# # Default TTL used when the backend does not specify one
# VARNISH_TTL=120
#
# # DAEMON_OPTS is used by the init script.  If you add or remove options, make
# # sure you update this section, too.
# DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
#              -f ${VARNISH_VCL_CONF} \
#              -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
#              -t ${VARNISH_TTL} \
#              -p thread_pool_min=${VARNISH_MIN_THREADS} \
#              -p thread_pool_max=${VARNISH_MAX_THREADS} \
#              -p thread_pool_timeout=${VARNISH_THREAD_TIMEOUT} \
#              -S ${VARNISH_SECRET_FILE} \
#              -s ${VARNISH_STORAGE}"
#


## Alternative 4, Do It Yourself
#
# DAEMON_OPTS=""

Burada Varnish 80 portunda çalışmasına ayarladık.

Şimdi de default.vcl dosyasını düzenleyelim. Bu düzenlemenin WordPress için özelleştirilmiş olduğunu, diğer çalışan sistemlerde sorun çıkarma ihtimalinin olduğunu belirtmek istiyorum.

Debian, Ubuntu  ve CentOS için

nano /etc/varnish/default.vcl

İçeriği aşağıdaki gibi değiştirin.

/* SET THE HOST AND PORT OF WORDPRESS
 * *********************************************************/
vcl 4.0;
import std;

backend default {
  .host = "127.0.0.1";
  .port = "8080";
  .first_byte_timeout = 60s;
  .connect_timeout = 300s;
}
 
# SET THE ALLOWED IP OF PURGE REQUESTS
# ##########################################################
acl purge {
  "localhost";
  "127.0.0.1";
}

#THE RECV FUNCTION
# ##########################################################
sub vcl_recv {

# set realIP by trimming CloudFlare IP which will be used for various checks
set req.http.X-Actual-IP = regsub(req.http.X-Forwarded-For, "[, ].*$", ""); 

        # FORWARD THE IP OF THE REQUEST
  if (req.restarts == 0) {
    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;
    }
  }

 # Purge request check sections for hash_always_miss, purge and ban
 # BLOCK IF NOT IP is not in purge acl
 # ##########################################################

  # Enable smart refreshing using hash_always_miss
if (req.http.Cache-Control ~ "no-cache") {
    if (client.ip ~ purge || !std.ip(req.http.X-Actual-IP, "1.2.3.4") ~ purge) {
         set req.hash_always_miss = true;
    }
}

if (req.method == "PURGE") {
    if (!client.ip ~ purge || !std.ip(req.http.X-Actual-IP, "1.2.3.4") ~ purge) {
        return(synth(405,"Not allowed."));
        }
    return (purge);
  }

if (req.method == "BAN") {
        # Same ACL check as above:
        if (!client.ip ~ purge || !std.ip(req.http.X-Actual-IP, "1.2.3.4") ~ purge) {
                        return(synth(403, "Not allowed."));
        }
        ban("req.http.host == " + req.http.host +
                  " && req.url == " + req.url);

        # Throw a synthetic page so the
        # request won't go to the backend.
        return(synth(200, "Ban added"));
}

# Unset cloudflare cookies
# Remove has_js and CloudFlare/Google Analytics __* cookies.
      set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
      # Remove a ";" prefix, if present.
     set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");

  # For Testing: If you want to test with Varnish passing (not caching) uncomment
  # return( pass );

  # FORWARD THE IP OF THE REQUEST
  if (req.restarts == 0) {
    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;
    }
  }

# DO NOT CACHE RSS FEED
 if (req.url ~ "/feed(/)?") {
    return ( pass ); 
}

## Do not cache search results, comment these 3 lines if you do want to cache them

if (req.url ~ "/\?s\=") {
    return ( pass ); 
}

# CLEAN UP THE ENCODING HEADER.
  # SET TO GZIP, DEFLATE, OR REMOVE ENTIRELY.  WITH VARY ACCEPT-ENCODING
  # VARNISH WILL CREATE SEPARATE CACHES FOR EACH
  # DO NOT ACCEPT-ENCODING IMAGES, ZIPPED FILES, AUDIO, ETC.
  # ##########################################################
  if (req.http.Accept-Encoding) {
    if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
      # No point in compressing these
      unset 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 {
      # unknown algorithm
      unset req.http.Accept-Encoding;
    }
  }

  # PIPE ALL NON-STANDARD REQUESTS
  # ##########################################################
  if (req.method != "GET" &&
    req.method != "HEAD" &&
    req.method != "PUT" && 
    req.method != "POST" &&
    req.method != "TRACE" &&
    req.method != "OPTIONS" &&
    req.method != "DELETE") {
      return (pipe);
  }
   
  # ONLY CACHE GET AND HEAD REQUESTS
  # ##########################################################
  if (req.method != "GET" && req.method != "HEAD") {
    return (pass);
  }
  
  # OPTIONAL: DO NOT CACHE LOGGED IN USERS (THIS OCCURS IN FETCH TOO, EITHER
  # COMMENT OR UNCOMMENT BOTH
  # ##########################################################
  if ( req.http.cookie ~ "wordpress_logged_in" ) {
    return( pass );
  }
  
  # IF THE REQUEST IS NOT FOR A PREVIEW, WP-ADMIN OR WP-LOGIN
  # THEN UNSET THE COOKIES
  # ##########################################################
  if (!(req.url ~ "wp-(login|admin)") 
    && !(req.url ~ "&preview=true" ) 
  ){
    unset req.http.cookie;
  }

  # IF BASIC AUTH IS ON THEN DO NOT CACHE
  # ##########################################################
  if (req.http.Authorization || req.http.Cookie) {
    return (pass);
  }
  
  # IF YOU GET HERE THEN THIS REQUEST SHOULD BE CACHED
  # ##########################################################
  return (hash);
  # This is for phpmyadmin
if (req.http.Host == "ki1.org") {
return (pass);
}

if (req.http.Host == "mysql.ki1.org") {
return (pass);
}

}

# HIT FUNCTION
# ##########################################################
sub vcl_hit {
  # IF THIS IS A PURGE REQUEST THEN DO THE PURGE
  # ##########################################################
  if (req.method == "PURGE") {
    #
    # This is now handled in vcl_recv.
    #
    # purge;
    return (synth(200, "Purged."));
  }
  return (deliver);
}

# MISS FUNCTION
# ##########################################################
sub vcl_miss {
  if (req.method == "PURGE") {
    #
    # This is now handled in vcl_recv.
    #
    # purge;
    return (synth(200, "Purged."));
  }
  return (fetch);
}

# FETCH FUNCTION
# ##########################################################
sub vcl_backend_response {
  # I SET THE VARY TO ACCEPT-ENCODING, THIS OVERRIDES W3TC 
  # TENDANCY TO SET VARY USER-AGENT.  YOU MAY OR MAY NOT WANT
  # TO DO THIS
  # ##########################################################
  set beresp.http.Vary = "Accept-Encoding";

  # IF NOT WP-ADMIN THEN UNSET COOKIES AND SET THE AMOUNT OF 
  # TIME THIS PAGE WILL STAY CACHED (TTL)
  # ##########################################################
  if (!(bereq.url ~ "wp-(login|admin)") && !bereq.http.cookie ~ "wordpress_logged_in" ) {
    unset beresp.http.set-cookie;
    set beresp.ttl = 52w;
#    set beresp.grace =1w;
  }

  if (beresp.ttl <= 0s ||
    beresp.http.Set-Cookie ||
    beresp.http.Vary == "*") {
      set beresp.ttl = 120 s;
      # set beresp.ttl = 120s;
      set beresp.uncacheable = true;
      return (deliver);
  }

  return (deliver);
}

# DELIVER FUNCTION
# ##########################################################
sub vcl_deliver {
  # IF THIS PAGE IS ALREADY CACHED THEN RETURN A 'HIT' TEXT 
  # IN THE HEADER (GREAT FOR DEBUGGING)
  # ##########################################################
  if (obj.hits > 0) {
    set resp.http.X-Cache = "HIT";
  # IF THIS IS A MISS RETURN THAT IN THE HEADER
  # ##########################################################
  } else {
    set resp.http.X-Cache = "MISS";
  }
}

default.vcl dosyasını düzenleyerek de, Varnish’in 80 portuna gelen istekleri alıp, arkaplanda 8080 portunda çalışan web sunucusuna iletmesini sağladık. Ayrıca WordPress için özelleştirilmiş olduğundan, WordPress siteniz üzerinde giriş yapmamış ziyaretçiler için web sunucunuz yerine Varnish üzerinden gösterim yapılacaktır. Üye girişi yapmış kullanıcılar ise Varnish cache sistemini atlayıp, onlar için websunucusu üzerinden gösterim yapılacaktır.

Şimdi ise websunucunuzun 80 portunu 8080 olarak değiştirmeye geldi. Bu düzenleme kullandığınız işletim sistemi, hosting paneli ve web sunucusuna göre değişiklik gösterdiğinden, kesin bir dosya yolu belirtemiyorum. Genel anlamı ile söylemek gerekirse Apache için httpd.conf içinde VirtualHost ayarlarını, Nginx için de nginx.conf içinde listen ayarını değiştirmeniz gerekiyor. Nano ile ayar dosyasını açtıktan sonra,

server {
        listen 80;
        server_name netkolik.org
<VirtualHost *:80>
    ServerAdmin [email protected]

kısmını

server {
        listen 8080;
        server_name netkolik.org
<VirtualHost *:8080>
    ServerAdmin [email protected]

olarak değiştirin.

Websuncusu ve Varnish yeniden başlatalım.

service httpd restart - CentOS için (Apache)
service apache2 restart - Debian/Ubuntu için (Apache)
service nginx restart - Nginx için
service varnish restart

Servisleri yeniden başlattıktan sonra Varnish 80 portunda Web sunucumuz 8080 portunda çalışır hale geldiler. Bu durumda Varnish 80 portuna gelen istekleri okuyup, eğer kendi bünyesinde önbelleğe aldı ise kendi üzerinden, eğer gelen istek önbellekte yok ise, 8080 portundaki web sunucusuna istekte bulunup, kendi önbelleğine alıp, aynı isteği diğer defa kendi önbelleğinden görüntüleyecektir.

Varnish Cache istatistikleri

SSH üzerinden varnishstat komutu ile Varnish istatistiklerini anlık olarak görüntüleyebilirsiniz.

varnishstat

Karşınızda top komutuna benzer bir ekran görüntüsü çıkacaktır.

Uptime mgt:     0+00:28:13                                                                                                         Hitrate n:        4        4        4
Uptime child:   0+00:28:13                                                                                                            avg(n):   0.0000   0.0000   0.0000

    NAME                                                                                  CURRENT        CHANGE       AVERAGE        AVG_10       AVG_100      AVG_1000
MAIN.uptime                                                                            0+00:28:13
MAIN.sess_conn                                                                                239          0.00           .            0.00          0.00          0.00
MAIN.client_req                                                                               283          0.00           .            0.00          0.00          0.00
MAIN.cache_hit                                                                                 93          0.00           .            0.00          0.00          0.00
MAIN.cache_miss                                                                                72          0.00           .            0.00          0.00          0.00
MAIN.backend_reuse                                                                            159          0.00           .            0.00          0.00          0.00
MAIN.backend_recycle                                                                          190          0.00           .            0.00          0.00          0.00
MAIN.fetch_length                                                                              51          0.00           .            0.00          0.00          0.00
MAIN.fetch_chunked                                                                            109          0.00           .            0.00          0.00          0.00
MAIN.fetch_204                                                                                 30          0.00           .            0.00          0.00          0.00
MAIN.pools                                                                                      2          0.00           .            2.00          2.00          2.00

Sol üstte görünen 0+00:28:13 ibaresi Varnish sunucumuzun 18 saat süre ile çalıştığını göstermektedir.
Hitrate ratio kısmı ise son 6 dakika içerisindeki Hitrate avg değerlerini vermektedir. 0.9968 değeri ise son 6 dakika içinde cache_miss/cache_hit değerlerinin oranıdır.
Sıralı şekilde görülen üç sütun ise; ilki toplam istek sayısı, anlık istek sayısı ve ratio oranlarıdır.
client_conn değeri, Varnish’in çalıştığı süre boyunca karşıladığı bağlantı sayısıdır.
client_req değeri, Varnish’in çalıştığı süre boyunca karşıladığı istek sayısıdır.
client_hit değeri, Varnish’in çalıştığı süre boyunca önbellekten gösterdiği istek sayısıdır.
client_hitpass değeri, Varnish’in çalıştığı süre boyunca doğrudan websunucusu üzerinden karşıladığı istek sayısıdır.
client_miss değeri, Varnish’in çalıştığı süre boyunca önbelleğe aldığı istek sayısıdır.

WordPress için Varnish ayarları

WordPress için hali hazırda W3 Total Cache kullanıyorsanız, Varnish sunucunuzu tanıtarak, Cache üzerindeki Page Cache ayarlarınız değiştikçe, Varnish Cache önbelleğinin değişmesini de ayarlayabilirsiniz. Bunun için, WordPress admin menüsünden, Performance > General Settings > Varnish yolunu takip ederek, Varnish sunucu IP adresini W3 Total Cache ile uyumlu olması için ayarlayabilirsiniz.

WordPress Varnish Cache

W3 Total Cache içinde bu ayarı aktif ederek, Page Cache ayarları doğrultusunda Varnish Cache ayarlarıyla entegre çalışmasını sağladık. Purge cache seçeneğine tıklayarak da önbelleği kendimiz de temizleyebiliriz.

W3 Total Cache kullanmıyorsanız da Varnish HTTP Purge adlı eklenti ile de aynı işi gerçekleştirebilirsiniz. (https://wordpress.org/plugins/varnish-http-purge/)

Varnish Cache HTTP Purge

default.vcl dosyamız, sadece WordPress ile uyumlu ayarlandığı için, çeşitli sitelerden sayfanızın header dosyasını görüntülediğinizde Varnish kullanılmıyor olarak gösterecektir. http://www.isvarnishworking.com/ adresinden sitenizi kontrol edebilirsiniz. Dosya özelleştirilmiş olduğundan Varnish header silinmiştir. Ama görebildiğiniz gibi Age ve X-Cache değişkenleri, Varnish’in çalıştığının göstergesidir.

X-Powered-By:    EasyEngine 3.4.0
X-Page-Speed:    1.9.32.6-7321
Cache-Control:    public, max-age=14400
Vary:    Accept-Encoding
X-Varnish:    458795 393247
Via:    1.1 varnish-v4
X-Cache:    HIT
CF-Cache-Status:    HIT
Expires:    Mon, 18 Jan 2016 21:21:09 GMT
X-Content-Type-Options:    nosniff
Server:    cloudflare-nginx
CF-RAY:    266bf98520dc188e-EWR
Content-Encoding:    gzip

(default.vcl dosyamızda Varnish headeri yerine X-Cache değeri HIT olarak döndürülmektedir)

Varnish özelliklerini sunucunuzdan anlık olarak varnishstat ve varnishtop komutları ile gözlemleyebilirsiniz.

4 Comments

Add a Comment

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Sayfa 0,262 saniyede 69 sorgu ile oluşturuldu.