Proxy Cache nedir ve nasıl kullanılır?
Bu flood’da Nginx
'in Proxy Cache
özelliği üzerinden bir önceki flood'da bahsedilen CDN
'in nasıl çalıştığını anlatacağım.
CDN
'in orijin sunucu ile istemci arasına girerek bütün istemciler için aynı olan (CSS
, JS
, imaj) gibi kaynakları cache'leyerek istemcilere ilettiğini söylemiştik. CDN
burada ilk istek için bir Proxy
sunucu, sonraki istekler için ise cache
sunucu gibi davranmaktadır.
Bütün trafiğin CDN
üzerinden geçtiği senaryoda (CloudFlare
, Fastly
) ise CDN
, cache'lenemeyecek (API, vb) kaynaklar için Reverse Proxy
görevi üstlenerek istemciden gelen isteği direkt olarak orijin sunucuya geçirip gelen cevabı ise tekrar istemciye iletir.
Önceki yazıların birinde Reverse Proxy
ve Forward Proxy
kavramlarının ne anlama geldiğini incelemiştik. Bu yazı https://medium.com/@gokhansengun/27f2a1fc634c linkinden incelenebilir.
CloudFlare
ve Fastly
'nin verdiği Reverse Proxy
ve Proxy Cache
hizmeti özel ihtiyaçlar
için açık kaynak kodlu Nginx
ve Varnish
yazılımları ile de yerine getirilebilir. Burada özel ihtiyaç
'tan kasıt aslında klasik anlamda bir CDN
ihtiyacı dışındaki ihtiyaçlardır. Örneğin, şirket içi ağda kullanıcıların yoğun olarak indirdikleri dosyalar yine şirket ağında bulunan bir sunucuya kurulacak Proxy Cache
yardımıyla cache'lenebilir. Bu sayede hem internetten indirilen bayt miktarı azaltılır hem de kullanıcılar zaman tasarrufu sağlar.
Bu yazıda sadece Proxy Cache
özelliğini inceleyeceğimiz Nginx
, C10k Problem
olarak bilinen ve onbin bağlantıyı aynı anda karşılama problemini çözmek üzere yola çıkmış bir web sunucu, yük dağıtıcı ve vekil sunucudur (Proxy Server
).
Nginx
ile Proxy Cache
konfigürasyonunun ilk adımı aşağıdaki gibi cache'lenecek kaynakların tutulacağı süre, disk bölgesi, vb detayların belirlenmesidir.
Konfigürasyonda belirtilen keys_zone=cache:10m
ile cache
adlı bir zone
yaratılarak bu alanda tutulacak kaynakların metadata
sı için 10 MB
yer ayrıldığı ifade edilmiştir. max_size=50g
direktifi ile ise tutulacak toplam dosya boyutu 50 GB
ile sınırlanmıştır. Bu sayede disk üzerindeki bütün boş alanın cache olarak kullanılması engellenmiştir. Toplam cache boyutu 50 GB
'ın üzerine çıktığında erişim zamanı bakımından en eski olan kaynaklar silinir. inactive=60d
direktifi ile ise 60 gün boyunca erişilmeyen kaynakların silinmesi belirtilmiştir.
Cachelenen kaynakların dosya ismi içeriğin hash’i olacak şekilde saklanır. Hash’i hesaplanan dosyaları bulma işlemini hızlandırmak için konfigürasyonda verilen levels=1:2
yönergesi uyarınca dosyalar aşağıdaki gibi klasörlere bölünmüş ve bir nevi tree
yapısı oluşturulmuştur.
Nginx
'in kaynakları hangi parametrelere göre cache'leyeceği proxy_cache_key
'e göre belirlenir. Aynı proxy_cache_key
'e sahip isteklere ilgili key
için cache'lenmiş cevap dönülür. Farklı isteklere aynı cevabı dönmemek için bu key
granüler olarak belirlenmelidir.
Nginx
'in sunduğu ileri seviye özelliklerinden biri proxy_cache_lock
'dur. Bu özellik ile Nginx
aynı proxy_cache_key
'e sahip olan isteklerin sadece birini orijin sunucuya geçirerek diğer istekleri belirli bir süre bekletir, gelen cevap bütün istemcilere iletilir.
proxy_cache_lock
özellikle cache temizlenme aralıklarında yapılan isteklerde upstream
veya origin
sunucuya fazla yük bindirmemek için çok önemlidir.
Nginx
, ön tanımlı olarak sunucudan gelen cevap başlığındaki Cache-Control
değeri Private
, No-Cache
veya No-Store
bulunan paketler ile Set-Cookie
bulunan paketleri cache'lemez çünkü sunucu bu başlıklarla cevapların kullanıcıya özel olduğunu açıkça belirtmektedir.
Bazı özel durumlarda (sunucunun cache’lenebilecek cevaplarda da ilgili başlıkları kullanması, vb) Nginx
'in yukarıda verilen default
davranışı proxy_ignore_headers Cache-Control;
direktifi ile ezilebilir.
Dikkat edilmesi gereken bir diğer husus Nginx
'in hatalı yapılandırıldığında orijin sunucudan gelen 4xx
ve 5xx
'li hata cevaplarını da cache'lemesidir. Özel durumlar hariç Nginx
sadece 2xx
ve bazen 3xx
'li cevapları cache'lemesi için yapılandırılmalıdır.
Yine dikkat edilmesi gereken önemli bir nokta Nginx
'in 3xx
'li redirect
cevaplarını ön tanımlı olarak takip etmeyerek direkt olarak sunucudan dönen değeri cache'lemesidir. Burada bu istekler proxy tarafından takip edilip asıl cevap cache'lenmeli ve istemciye sunulmalıdır.
Proxy Cache
kullanılırken Proxy
'nin istemciye döndüğü cevap başlığında isteği cevaplarken cache
kullanılıp kullanılmadığını belirtmek için HIT
, MISS
, vb yazmak hem cache kullanımını görmek hem de problemleri debug etmek için iyi bir pratiktir.
Son olarak Nginx
'in Proxy Cache
özelliği geliştirme ortamlarının evcilleştirilmesi için sıklıkla tercih edilmektedir. En yaygın iki örnek şirket içindeki bir sunucuda Proxy Cache
ile NPM
repolarını ve Docker imajlarını cache'lemek olarak verilebilir.