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 webmaster@
kısmını
server { listen 8080; server_name netkolik.org
<VirtualHost *:8080> ServerAdmin webmaster@
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 İstatistikleri
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.
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/)
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.
İlla aynı sunucuda olmak zorunda da değil. Varnish’i farklı bir sunucuya kurarak daha yüksek performans elde edebilirsiniz.
Evet dediğiniz gibi. Sadece aynı sunucu üzerine değil de farklı sunucu üzerinde de kurulabilir.
Merhaba,
Directadmin’de servislerde httpd ve nginx görünüyor. Fakat RAM kullanımı httpd’de daha fazla (1 gb). Nginx (70 mb) atıl durumda bekliyor gibi. Verdiğiniz sitede de server kısmında Nginx yazıyor.
Server: nginx
Date: Wed, 13 Jul 2016 10:14:24 GMT
Content-Type: text/html; charset=UTF-8
Bu durumda biz nginx dosyasını mı düzenleyeceğiz yoksa apache mi?
Şu an Varnish kurulumunu yaptık portları ayarlamadık. Dosyalarda ayarlar şöyle;
Varnish:
#DAEMON_OPTS=”-a :6081 \
-T localhost:6082 \
-b localhost:8080 \
-u varnish -g varnish \
Default.vcl:
backend default {
.host = “127.0.0.1”;
.port = “8080”;
Ayrıca biz 16GB RAM kullanıyoruz. Verdiğiniz ayarları direkt kullanabiliyor muyuz?
Tşk.
Nginx kullandığınız için, Ngix içinde gerekli port ayarlarını yapacaksınız.
backend default {
.host = “127.0.0.1”;
.port = “8080”;
kısmı arka tarafta çalışan Apache/Nginx ayarlarını yapıldığı bölümdür.
Nginx üzerinden portu 8080 olarak düzenlerseniz herhangi bir sıkıntı yaşamazsınız.