Nginx, Igor Sysoev tarafından yazılan bir http, reserve ve mail proxy sunucudur. Güncel bir istatistiğe göre Nginx sunucusu bugün, dünya genelinde yayında olan web sitelerinin %15’inde kullanılmakta ve pazar konumunu büyütmektedir.
Nginx kullanıcıları arasında
- wordpress.com
- yandex.ru
- tumblr.com
- pinterest.com
- instagram.com
- cnn.com
Söz konusu bu istatistiği ve popüler kullanıcıları açıklayacak sebepler olarak, Nginx’in sağladığı avantajların altı çizilebilir.
- Kolay konfigürasyon
- Minimum bellek tüketimi
- Yüksek performans
- Yük dengeleme(load balancing)
- Otomatik yerine çalışma (failover)
Bu yazıda, Nginx hakkında öncelikle bilinmesi gereken 3 nokta üzerinde duracağız. Bunlardan ilki kolay yapılandırma, ağırlıklı olarak ele alacağımız diğer 2 nokta ise Nginx’in düşük bellek tüketimi ve yüksek performansı nasıl sağladığı olacak. Nginx, diğer pekçok http sunucusunda varolana benzer karmaşık xml yapılandırmasına sahip değildir. Nginx yapılandırması, .conf uzantılı düz metin dosyasıyla gerçekleştirliyor. Söz dizimi oldukça basit ve yalın.
Bir örnek: nginx.conf
Yukarıda, Nginx’in çalıştığı 80 portunu dinleyen 3 sunucunun olduğu bir yapılandırma örneği görülüyor.
YÜKSEK PERFORMANSIN SIRRI!
Düşük bellek kullanımı ve buna bağlı olarak yüksek performans, Nginx’in anılması gereken en önemli artılarından. Bu noktada, Nginx’in bu artı değeri nasıl sağladığına yakından bakmaya çalışacağız.
Bugün, yaygın olarak kullanılan pek çok http sunucusu(örn Apache) blocking model olarak anılan bir mimariye sahiptir. Bu mimaride her request için bir soket açılır ve buna bağlı olarak bir thread işletilir, bu thread için de belirli bir bellek tahsis edilir. Yürütme, soket bağlantısı sağlanana kadar bekler.
Bu mimari, yoğun trafik alan sistemlerde c10k olarak anılan soruna yol açabilmektedir. Sorunun kaynağında, işletim sistemlerinin multitask’ı gerçekleştirme biçimi yatmaktadır.
PREEMPTIVE MULTITASKING & CONTEXT SWITCHING
Multitasking bir işlemcinin birden fazla görevi, aynı zamanda yürütebilmesine olanak sağlayan bir yöntemdir. Bu yöntemde aynı anda birden fazla işlemin gerçekleştirilebilmesi adına, verilen görevler thread’ler üzerinde çalıştırır. Bu mimaride bir thread yürütülürken herhangi bir sebeple kesilebilir(interrupt) ve bir başka thread yürütülebilir. Kesilen thread’in durumu, kalınan yerden devam edebilmesi adına kaydedilir ve thread tekrar yürütüleceğinde bu kayıt geri yüklenir. Bir işlemcinin bir görevden diğerine bu şekilde yeniden atama yapma eylemi context switch olarak adlandırılmaktadır.
İşlemci bu şekilde, sırada bekleyen tüm thread’ler arasında gezinebilir ve context switch eylemi yeterli sıklıkta meydana geldiğinde, thread’lerin paralel yürütüldüğü gibi bir yanılsama elde edilir.
Anılan bu mimaride, bir zaman ve bellek maliyeti söz konusudur. Zaman maliyeti, bir thread’in beklemeye alınıp(block/waiting) diğerinin hazır(ready)’dan çalışır duruma(running state) getirilmesi süreçleri arasında, bellek maliyeti ise her bir thread’in oluşturulmasıyla gerçekleşir.
Nispeten düşük sayılı thread’lerde oluşan bu maliyet, özellikle günümüzün güçlü işlemcileri bakımından ihmal edilebilecek boyutlarda olabilir, ancak thread sayısı arttıkça maliyet de artmaktadır.
Yukarıda ifade edildiği gibi blocking model olarak anılan mimariye sahip http sunucuları, her bir request için yeni bir thread oluştururlar. Bu durum, eş zamanlı ziyaretçi sayısının artmasıyla birlikte c10k probleminin doğmasına sebebiyet verir. Bu sonucu doğuran en önemli faktör, context switch sebebiyle, sistemin cevap verme süresinin uzaması ve bellek ihtiyacının artmasıdır.
Farklı bir bakış açısı, model ve mimari yaklaşımla bu bahsedilen problemler ortadan kaldırılabilir mi?
Nginx, bu soruya verilmiş çok güzel bir “evet” cevabıdır.
ASYNCHRONOUS EVENT-DRIVEN MODEL
Nginx, yukarıda anılan mimari modelden farklı olarak, request’leri işlemek için olay-güdümlü, asenkron bir mimariye dayanır. Nginx her request için ayrı bir proses(thread) işletmek yerine, bir ana işlem(main process) içinde, asenkron çağrılarla çok sayıda işçi işlemler(workers, imtiyazsız kullanıcı olarak yürütülürler) kullanmaktaktadır.
Nginx her işçi’ye, verilen görevin gerçekleşimi ile ilintili bir event handler bağlar. Görev alan işçi işi tamamladıktan sonra bir event fırlatır ve bu event, kendisine bağlı handler tarafından yakalanır. Bu sayede, context switch gibi bir mekanizmaya ihtiyaç kalmaz ve thread sayısı arttıkça artan bekleme süresi ve buna bağlı sistemin geç yanıt vermesi gibi sorunlar ortadan kalkar.
Aşağıda, eş zamanlı yüksek trafik alan Nginx ve Apache sunucularına dair benchmark sonuçlarından elde edilmiş bir grafik görüyorsunuz.
Grafikte görüldüğü üzere Apache sunucusunun gelen isteklere verdiği cevaplar, eş zamanlı istemci sayısının artmasıyla düşüyor. Oysa istemci sayısının artması, özellikle 1000 eş zamanlı istek sonrasında Nginx sunucunu çok etkilemiyor.
Bu grafikte ise, artan eş zamanlı istemci sayısına bağlı olarak, sunucuların ihtiyaç duyduğu bellek miktarı görülüyor. Apache, yeni gelen istemciler için yeni thread’lere ve bu thread’ler için artı belleğe ihtiyaç duyuyor. Oysa olay güdümlü asenkron çağrım yaklaşımıyla çalışan Nginx’in bellek ihtiyacı, artan istemci sayısına rağmen sabit kalıyor, çünkü thread sayısı değişmiyor.
Çok daha güncel bir başka benchmark sonucu da aşağıda görülüyor.
Sonuç
Sonuç olarak Nginx’in, farklı mimari tarzı, sağladığı performans, yük dengeleme ve otomatik yerine çalışma gibi artılarıyla, yüksek trafik alan sistemler için çok cazip bir çözüm olduğunu ifade edebiliriz.
kaynak : https://kodcu.com/2013/12/nginx/
Yorumlar
Yorum Gönder