Varnish kurulumu ve yükdağılımı yapmak (Load Balancing)

Varnish son zamanlarda popüler olmaya başlayan bir web proxy sunucusudur. Bu dökümanda Varnish’in basitçe kurulumunu ve Varnish ile yük dağılımı yaparak web sunucunuza düşen yükü nasıl azaltabileceğinize değineceğim. Anlattığım ayarlar Ubuntu için olacak ancak diğer Linux dağıtımlarında da aynı şekilde çalışacaktır.


Varnish, Linux tabanlı olup popüler Linux dağıtımlarının depolarında bulunmaktadır. Son versiyonunu kullanmak istiyorsanız yine Ubuntu ve Redhat için Varnish’in kendi depoları mevcut. Ubuntu için örnek verecek olursak:

  1. curl http://repo.varnish-cache.org/debian/GPG-key.txt | sudo apt-key add -
  2. echo "deb http://repo.varnish-cache.org/ubuntu/ <ubuntu_dagitim_adi> varnish-3.0" | sudo tee -a /etc/apt/sources.list
  3. sudo apt-get update
  4. sudo apt-get install varnish

Adımlarını takip ederek en son versiyonunu kurabilirsiniz.
Varnish’in asıl görevi proxy sunucusu olmak, ancak desteklediği diğer özellikler ile çok hafif bir yük dağıtım sunucusu olabilmektedir.

Yük dağıtım senaryoları aşağıdaki gibi olabilir:

  1. Tek sunucu üzerinde web sunucusunu farklı bir portta çalıştırıp (örn. 8080) Varnish’i 80. portta çalıştırmak
  2. Birden fazla web sunucusunun önüne bir (veya daha fazla) Varnish sunucusu yerleştirip yük dağılımı yapmak

Varnish kurulumu yaptıktan sonraki ilk aşama Varnish’in çalışacağı portu belirlemek ve buna göre web sunucusunun (veya sunucularının) portlarını ayarlamak olacaktır. Varnish’in standart ayarları /etc/default/varnish dosyasında bulunmaktadır. Burada yapılması gereken şey DAEMON_OPTS ile başlayan satırdaki ayarlamaları yapmaktır. Bu satırda -a parametresi Varnish’in hangi ip ve portta çalışacağını belirler. -s parametresi ise proxy için ayrılacak hafıza miktarını belirler. Varnish’in hızlı olmasının en büyük sebebi proxy için disk kullanmadan sadece ram kullanması ve log tutmak için yine disk kullanmamasıdır. Varnish’in logları tutulmadığı için loglarını anlık görmek için varnishlog komutunu kullanabilirsiniz.

Bu ayarları yapıp Varnish’i başlattığınızda standart kurulum tamamlanmış olacaktır.

Varnish’in web siteleri ile ilgili ayarları ve uyduğu kuralların bulunduğu dosya ise /etc/varnish/default.vcl dosyasıdır. Yeni ayarlar yapmak için bu dosyayı düzenleyebilir veya isteğe bağlı olarak farklı dosyalar yaratıp Varnish’in bunları kullanmasını sağlayabilirsiniz. Varnish ile load balancing yapmak çok kolay. Yukarda bahsettiğimiz senaryolara göre ayarları şu şekilde:

1. Tek Sunucu üzerinde çalıştırmak:

Bu kullanım tipinde web sunucu farklı bir portta çalışır (örn. 8080) ve Varnish 80. portta çalışarak, gerekli durumlarda web sunucusuna bağlantı kurar.
Default.vcl dosyasındaki ayarlar şu şekilde olacaktır:

backend default { .host = "127.0.0.1"; .port = "8080"; }

Bu ayar sonrasında Varnish gelen her isteği 8080. portta çalışan web sunucuya gönderecektir. Ayrıca statik dosyaların hafızada tutulup bir daha istendiğinde web sunucuya gitmeden direk hafızadan sunulması, belli kurallar dışındaki bağlantıların web sunucuya gönderilmemesi gibi birçok ayar yapılabilir. Bu konular 2. tip kullanımda da aynı şekilde olduğu için aşağıda ayrıca anlatacağım.

2. Birden fazla web sunucuya yük dağılımı yapmak:

Bu kullanım tipinde birden fazla web sunucu kurulumu yapılır ve bunların önüne bir veya birden fazla Varnish sunucusu konur. Gelen tüm istekler Varnish’e gelir ve belli kurallara göre web sunuculara yönlendirilir. Bu çalışma tipinde arkadaki web sunuculardan birinde bir sorun olduğunda istekler diğer sunuculara yönlendirilir. Böylece kesintisiz hizmette sağlanmış olur.

Default.vcl dosyasındaki ayarlar şu şekilde olacaktır (2 web sunucu için):

backend web1 {
  .host = "10.0.0.1";
  .probe = {
                .url = "/";
                .interval = 5s;
                .timeout = 1s;
                .window = 5;
                .threshold = 3;
  }
}

backend web2 {
  .host = "10.0.0.2";
  .probe = {
                .url = "/";
                .interval = 5s;
                .timeout = 1 s;
                .window = 5;
                .threshold = 3;
  }
}

Burada web sunucularımızın ip tanımlarını yaptık. Ayrıca .url seçeneği ile bu url’yi test etmesini, 5 saniyede bir yapılacak 5 denemeden 3 tanesinde hata alırsa bu sunucuyu arızalı olarak görmesini istedik. Bu değerleri kendi isteğinize göre değiştirebilirsiniz.

director havuz round-robin {
        {
                .backend = web1;
        }
        {
                .backend = web2;
        }
}

Burada web sunucularımızdan bir sunucu havuzu oluşturduk. Artık bir web sitesine sen “havuz” isimli sunucu havuzuna git deme şansımız var. Burdaki tanımda verdiğimiz “round-robin” ayarının anlamı her gelen isteği sırasıyla havuzdaki sunuculara yönlendirmek demek. Yani ilk istek geldiğinde web1’e gidecek, 2. istek web2’ye gidecek. 3. istek yine web1’e gidecek.

Burada kullanabileceğimiz diğer seçenekler ise:

  • random: rasgele bir sunucu seçilip, istek ona yönlendirilir
  • client: bağlantı kuran kişiye göre bir sunucu seçilip o kişinin hep aynı sunucuya bağlanmasını sağlamak için kullanılır
  • hash: bağlanılan URL ile bir hash oluşturulup ona göre yönlendirme yapılır
  • fallback: ilk sağlıklı web sunucu seçilip tüm bağlantılar ona yönlendirilir, o sunucuda bir problem olursa, diğer sunucuya geçilir

Ayarlarda son olarak Varnish’e o siteye gelen bağlantıları sunucu havuzuna yönlendirmesini söylememiz gerekiyor, bunun için default.vcl dosyasındaki vcl_recv bölümüne aşağıdaki gibi bir ayar yapmak gerekiyor:

sub vcl_recv {
   if (req.http.host ~ "^(www.)?benimsitem.com$") {
       set req.backend = havuz;
   }
}

Artık benimsitem.com’a giren bir kişi Varnish üzerinden arkadaki web sunuculara yönlendirilecek.

Yapılabilecek diğer uygulamalar:

Varnish yukardaki şekilde kullanıldığında sadece gelen trafiği web sunuculara yönlendirecektir. Ancak buna ek olarak web sunucuların yükünü hafifletmek için çeşitli ek ayarlamalar yapılabilir:

  • Statik dosyalar (jpg dosyaları, içeriği değişmeyen html dosyaları vs.) için proxyleme yapılıp, aynı dosyayı defalarca web sunucudan istemeden direk hafızadan sunabilir. Bunlar için belli süreler ayarlanıp, o süre dolduğunda tekrar web sunucudan istek yapılması sağlanabilir
  • Olası bir saldırı veya DDOS durumunda gelen istekler Varnish tarafında filtrelenip web sunucunun bu gereksiz isteklere cevap vermeye çalışıp zorlanması engellenebilir
  • Web sunucuların tamamı çöktüğü gibi bir durumda belli sayfaların proxy üzerinden sunulması sağlanabilir. Örneğin bir haber sayfasında ana sayfa Varnish üzerinde 5 saniyelik bir süre ile proxy yapılmaktayken, web sunucular çöktüğünde, Varnish’in cache süresini uzatıp, ana sayfayı hafıza üzerinden vermeye devam etmesi sağlanabilir. Böylece web sunucular kapalı olsa bile ana sayfa çalışmaya devam edecektir.

Varnish genel olarak bu şekillerde kullanılmakla beraber basit ve geliştirilebilir konfigurasyon yapısı sayesinde çok daha farklı şekillerde de kullanılabilmektedir. Daha öncede bahsettiğim diske log yazmaması gibi birçok özelliği ile yüzbinlerce bağlantıya hiç zorlanmadan cevap verebilir.

Benim Varnish’te tek gördüğüm eksik SSL desteği olmaması. Bunu da geliştiricileri SSL şifrelemesinin yapılmasının programa çok fazla yük getireceği ve kullanım amacını bozacağı yönünde açıklamışlar.

4 thoughts on “Varnish kurulumu ve yükdağılımı yapmak (Load Balancing)

  1. umutbesler Post author

    Merhaba Emrah Bey,

    Apache’nin rpaf modulu ile bahsettiğiniz sorunu çözebilirsiniz. rpaf modülünün kullanımını araştırırsanız basit bir config yapısı var.

  2. Emrah AK

    Merhabalar,

    Yaziniz icin tesekkkurler birtakim sorulari cevaladi. Sormak istedigim bir sorum var, suan mevcut cpanel apache+varnish sunucuda ip adresleri apachede loglanmiyor. apache loglarina baktigimda dogrudan web server ip adresini yaziyor loglara.

    kullanici ip adresinin apache loglarina yazilmasini nasil saglarim.

    iyi calismalar.

  3. umutbesler Post author

    Merhaba Ensar bey,

    Birden fazla Varnish kurulumu için ilk aklıma gelen 2 yöntem var:
    1. Birden fazla fiziksel sunucu kurup hepsinde Varnish kurulumu yapmak
    2. Bir fiziksel sunucu üzerinde farklı ip adreslerinde birden fazla Varnish çalıştırmak

    1. seçenek için yapılması gereken ekstra birşey yok. Farklı sunucular kurup üzerlerinde Varnish kurulumu ve ayarlamaları yapılması yeterlidir.

    2. seçenek için Varnish’i kendinizin derlemesi gerekecektir. Farklı klasörlerde Varnish’i derleyip, her birini farklı ip adreslerinde çalışacak şekilde ayarlayıp sonra hepsini ayrı ayrı başlattığınızda her ip adresinde farklı Varnish sunucuları çalışmış olacaktır.

    Her iki kurulumda da bu sefer Varnish’e gelen trafiği kurulu Varnish sunucularına yönlendirecek bir yapı gerekecektir. Bunun için en basitinden DNS yönlendirmesinde Round Robin metodu kullanılarak, gelen isteklerin sırayla Varnish sunucularının hizmet verdiği ip adreslerine yönlendirmeleri sağlanabilir.

    Varnish’in malesef kendi cluster özelliği bulunmuyor. Varnish geliştiricileri, programın çalışma hızını kaybetmemesi ve sorunsuz çalışmaya devam edebilmesi için bu tarz ek özellikleri eklemeden sadece programın kendi ana konusunda çalışmasını istedikleri için bu tarz özellikler yok.

    Varnish’in SSL desteği yok ve SSL yönlendirme özelliğide yok. SSL yönlendirmesi için farklı yazılımlar kullanmak gerekiyor. SSL içinde Nginx’in load balance özelliği kullanılabilir. Nginx sadece 443. portlarda çalışacak şekilde ayarlanıp aynı load balancing ayarları yapılarak çalıştırılabilir. Tabi burda ayarlamalar Varnish’e göre daha zor olacaktır.

  4. Ensar

    Merhaba,
    Makaleniz için teşekkürler, güzel bir bilgilendirme yazısı olmuş.
    Bir kaçtane sormak istediğim soru var;
    2 adımda bahsettiğiniz birden fazla varnish sunucusu kurulumu nasıl yapılabilir. Varnish’in kendi cluster özelliği varmıdır ?. Bir sunucu yerine 2 varnish sunucu nasıl koyabiliriz.
    Ayrıca SSL desteği yok ancak, backend deki sunuculara SSL isteğini direk nasıl yönlendirebilir.
    Teşekkürler.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.