Siteyi CDN'ye taşıdınız ve şimdi giriş yapmış bir kullanıcı sayfayı misafir modunda görüyor. Ya da daha kötüsü: birinin alışveriş sepeti bir sonraki kişiye gösteriliyor. Sunucu logunu açarsanız, /account isteklerinin 200 (HIT) durum koduyla yanıtlandığını görürsünüz, oysa bunların kaynaktan gelmesi gerekir. İşte tam bu noktada CDN yapılandırması "CDN'yi etkinleştirmek"ten ayrılır.
Sorun CDN'nin kendisinde değil. Sorun, uç noktaya neyi önbelleğe alacağını söylemiş olmanız ve bu talimatın dinamik uygulamanızın gerçeğiyle uyuşmamasıdır.
Tehlikeli varsayılan: Her şeyi dosya uzantısına göre önbelleğe almak
Çoğu CDN panelinde "statik dosyaları önbelleğe al" diyen hazır bir kural vardır. O kuraldaki "statik" tanımı genellikle uzantıya dayanır: .css, .js, .jpg, .woff2. Buraya kadar doğru. Felaket, bu kuralı uzantısı olmayan ama arkasında dinamik olan yollara uyguladığınızda başlar.
/api/v1/cart gibi bir URL'nin hiç uzantısı yoktur, bu yüzden ilk bakışta statik görünmez. Ancak önbellek kuralınız "her şey /assets/ altında" ise ve biri yanlışlıkla bir endpoint'i aynı yolun altına koyarsa, o andan itibaren kişiselleştirilmiş yanıtlar önbelleğe alınır.
Doğru kural şudur: önbelleğe alma kararını yola göre değil, kaynak yanıt başlığına göre verin. Uygulamanız Cache-Control: private, no-store döndürüyorsa, CDN bunu aynen saygıyla karşılamalıdır.
Neyin önbelleğe alınacağını hangi başlıklar belirler
Üç ana başlık vardır ve önem sıralaması sabittir.
Cache-Control: En önemlisi. Sürümlenmiş dosyalar içinpublic, max-age=31536000, immutabledeğeri, kullanıcı oturumuna bağlı her şey içinprivate, no-store.Vary: YanıtAccept-EncodingveyaAccept-Language'e göre farklıysa, bu belirtilmelidir. Bu olmadan, gzip sürümü gzip anlamayan bir tarayıcıya ulaşır.Set-Cookie: Yanıtta varsa, temkinli CDN'ler o yanıtı önbelleğe almaz. CDN'niz bunu görmezden geliyorsa, alışveriş sepeti sorunu tam orada doğar.
Pratik bir not: Kaynak Nginx'te kişisel yollar için şu satırı ekleyin:
location /account/ {
add_header Cache-Control "private, no-store, max-age=0";
add_header Vary "Cookie, Accept-Encoding";
}
Ve sürümlenmiş statik dosyalar için:
location ~* \.(css|js|woff2|webp)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
31536000 sayısı bir yıl demektir. Bu sayı yalnızca dosya adı içerik hash'i içerdiğinde güvenlidir, örneğin app.4f9c2a.js. Dosya adı sabitse, bir yıl önbellek kullanıcının bir yıl boyunca eski sürümü görmesi demektir.
Sorgu dizesi: Çoğu sitenin yanlış karar verdiği nokta
Çoğu CDN'nin varsayılanı, tüm sorgu dizesini önbellek anahtarına dahil etmektir. Yani /style.css?v=1 ve /style.css?v=2 uç noktada iki ayrı nesnedir. Bu davranış güvenlidir ancak önbellek isabet oranını düşürür.
İkinci durum, sorgu dizesini tamamen görmezden gelmektir. Bu, önbellek isabet oranını yükseltir ve karşılığında ince bir hata yaratır: sorgu parametreleri içeriği etkiliyorsa, yanlış yanıt sunulur.
Üçüncü durum, ki benim varsayılan tercihimdir, beyaz liste yöntemidir. Yalnızca içeriği gerçekten değiştiren parametreler önbellek anahtarında kalsın:
# yalnızca bu parametreler cache key'de kalsın
v, ver, version, lang, currency
utm_source, gclid ve fbclid gibi parametreler çıkarılmalıdır. Çıkarılmazsa, her reklam kampanyası aynı sayfanın uç noktada yeni bir sürümünü oluşturur ve önbellek isabet oranınız sebepsiz düşer. Bir projede tam da bu oldu: önbellek isabet oranı %91'den %34'e düştü çünkü e-posta bağlantılarının hepsinde utm_ vardı.
Çerezler ve kullanıcı oturumu
CDN'niz "çerez varsa önbelleğe alma, yoksa al" şeklinde ayarlanmışsa iki durum ortaya çıkar. Misafir kullanıcı önbelleğe alınır, giriş yapmış kullanıcı alınmaz. Bu mantıklı görünür ve pratikte haber ve e-ticaret siteleri için işe yarar.
Ancak sorun şu ki, birçok site analitik çerezi veya çerez banner'ı çerezi gibi gereksiz çerezleri tüm ziyaretçilere yerleştirir. Sonuç: hiç kimse önbelleğe alınmaz ve CDN'niz sadece pahalı bir proxy olur.
Çözüm, oturum çerezini diğerlerinden ayırmaktır. Örneğin PHP'de oturum adını APPSESSID gibi bir şeye değiştirin ve CDN'de yalnızca bu adı karar kriteri olarak kullanın. Analitik çerezi artık önbelleği etkilemez.
İşte burada hata yapılıyor: Ekipler önbelleğe alınması için çerezi yanıttan kaldırıyor, oysa o çerezin CSRF için gerekli olduğunu bilmiyorlar. Belirtisi şudur: Formlar birkaç saat çalışır ve sonra aniden 419 Page Expired verir. Bu hatayı görürseniz, önce form koduna değil, CDN önbellek ayarlarına bakın.
Yayından sonra önbelleği geçersiz kılma
İki yaklaşım vardır ve aralarındaki seçim yayın şeklinize bağlıdır.
| Yöntem | Maliyet | Nerede işe yarar |
|---|---|---|
| URL'ye göre Purge | Yavaş, kesin yol listesi gerektirir | Manuel yayın yapan küçük siteler |
| Dosya adını sürümleme | Build pipeline'ında değişiklik gerektirir | CI/CD'si olan her site |
| Tam purge (purge all) | Geçici olarak tüm trafik kaynağa gider | Yalnızca acil durumda |
Ben her zaman sürümlemeyi seçerim. Tam purge'ü yalnızca yanlış bir yanıt tüm kullanıcılara sunuluyorsa ve derhal durdurulması gerekiyorsa uygularım. O anda kaynağınız tam yükü kaldırabilmelidir; kaldıramıyorsa, tam purge kendisi ikinci bir olay yaratır.
Altyapınız yönetilen Kubernetes üzerinde çalışıyorsa, dosya adı sürümlemesini aynı build pipeline'ına koyabilir ve bir daha asla manuel purge yapmazsınız. Ağır statik trafiği olan siteler için, dosyaları nesne depolama alanına ayırıp uç noktadan sunmak, yükü kaynaktan tamamen kaldırır.
Asla önbelleğe almamanız gerekenler
- Kullanıcı oturumuna göre değişen her yol: alışveriş sepeti, kullanıcı paneli, ödeme sayfası.
POST,PUTveDELETEyanıtları. Bunlar varsayılan olarak önbelleğe alınmaz, ancak bazı hatalı yapılandırmalar bunu yapar.Set-Cookiebaşlığı olan her yanıt.5xxkodlu hata sayfaları. CDN bir502'yi beş dakika önbelleğe alırsa, beş dakika boyunca herkese hata gösterilir.
Dördüncü maddeyi ciddiye alın. Bazı CDN'lerin varsayılanı, kaynağın nefes alması için hata yanıtlarını kısa süreliğine önbelleğe almaktır. Bu davranış DDoS saldırısında yardımcı olur ancak geçici bir veritabanı hatasında hasar alanını büyütür.
Pratikte işlerin sırası
Önce kaynak başlıklarını düzeltin, sonra CDN'yi açın. Tersini yaparsanız, aynı anda iki değişkenle savaşmak zorunda kalırsınız ve hangi katmanın yanlış yanıt ürettiğini anlayamazsınız.
Açtıktan sonra curl -I ile birkaç kilit yolu kontrol edin:
curl -I https://example.com/account/
curl -I https://example.com/assets/app.4f9c2a.js
curl -I "https://example.com/product?utm_source=news"
Çıktıda X-Cache: HIT veya CF-Cache-Status arayın. İlk yol MISS veya BYPASS olmalıdır. İkinci yol HIT olmalıdır. Üçüncü yol, parametresiz yolun aynı önbellek anahtarını döndürmelidir.
Sitenizin trafiği değişkense ve uç noktanın ne kadar dayanabildiğini bilmek istiyorsanız, CDN yapılandırmasında herhangi bir değişiklik yapmadan önce yanıt sürelerinden bir temel değer alın. Sunucu izleme ve uyarı kurulumu rehberi tam da bunu kapsar ve o olmadan her değişiklik bir tahmindir.
Gelen trafiği öngörülemeyen siteler için, CDN'yi ServerNet bulut sunucusu ile birleştirmek, kaynak kapasitesini uç noktadan bağımsız olarak ayarlama imkanı verir. Gerekirse, bulut altyapısı (IaaS) da kaynak katmanı üzerinde tam kontrol sağlar.
Sık sorulan sorular
CDN'yi etkinleştirdikten sonra neden giriş yapmış kullanıcılar misafir olarak görünüyor?
Çünkü kullanıcı oturumuna bağlı sayfanın yanıtı uç noktada önbelleğe alınmış ve bir sonraki kullanıcıya da aynı yanıt veriliyor. Nedeni genellikle kaynak yanıtında Cache-Control: private, no-store başlığının olmamasıdır. Bu başlığı eklemediğiniz sürece, CDN panelindeki her ayar sorunun yalnızca bir kısmını örter.
Kalıcı çözüm, önbellek kararını kaynağa bırakmak ve CDN'de yalnızca "kaynak başlığına saygı göster" demektir.
Sorgu dizesini CDN önbellek anahtarında tutmalı mıyım?
Yalnızca içeriği gerçekten değiştiren parametreleri. utm_source ve gclid gibi izleme parametreleri çıkarılmalıdır, aksi halde her kampanya bağlantısı uç noktada yeni bir sürüm oluşturur ve önbellek isabet oranı düşer.
lang veya currency gibi parametreler kalmalıdır, çünkü yanıt gerçekten farklıdır.
Yeni sürüm yayınlandıktan sonra önbelleği nasıl geçersiz kılarım?
En iyi yöntem, buna hiç gerek kalmamasıdır: statik dosya adlarını içerik hash'i ile sürümleyin, böylece yeni URL yeni bir önbellek anahtarı oluşturur. Tam purge'ü acil durumlar için saklayın, çünkü o anda tüm trafik kaynağa gider.
Purge yapmak zorundaysanız, önce kaynağın tam yükü kaldırma kapasitesine sahip olduğundan emin olun.
Dinamik HTML sayfalarını önbelleğe almak gerçekten değerli mi?
Evet, tüm kullanıcılar için aynı olan sayfalar için: ana sayfa, ürün listesi, makaleler. Bunlar genellikle en fazla trafiğe sahiptir ve önbelleğe alınmaları veritabanı yükünü ciddi ölçüde azaltır.
Ancak kullanıcı çerezine göre değişen her sayfa için yanıt açıktır: hayır. Sınırı tahmine göre değil, Vary başlığına ve Set-Cookie varlığına göre çizin.
Her şeyden önce, bugün curl -I ile sitenizin üç kilit yolunu kontrol edin. Kullanıcı paneli yolu HIT döndürüyorsa, geri kalan tüm tartışmalar anlamsızdır.
Yorumlar 0
Henüz yorum yok — ilk siz olun!