"Sistem kaç kullanıcıyı kaldırır?" sorusunun cevabı tahminle değil, ölçümle verilir. Bu cümleyi ofiste o kadar çok tekrarlıyorum ki ekip artık ben söylemeden koro halinde tamamlıyor. Ama arkasında acı bir hatıra var: birkaç yıl önce bir müşterimiz, bizim de uyarımıza rağmen yük testine "gerek yok, sunucu güçlü" demişti. TV reklamı yayınlandı, dakikalar içinde trafik 40 katına çıktı, veritabanı bağlantı havuzu doldu ve site kampanyanın en tatlı saatinde kapandı. Reklam bütçesi ekrandaki hata sayfasına aktı.
O günden beri yük testi bizim projelerimizde pazarlık konusu değil. Bu yazıda yaklaşımımızı, araç tercihlerimizi ve sahada öğrendiklerimizi anlatacağım.
k6 ile JMeter arasında nasıl seçim yapıyoruz
İki aracı da yıllardır aktif kullanıyoruz, ikisinin de dosyası kabarık.
k6, senaryoları JavaScript ile yazdığınız, komut satırından koşan modern bir araç. Geliştirici ekipler için ilk tercihimiz; çünkü senaryo dosyası kod gibi versiyonlanıyor, code review'dan geçiyor ve CI hattına doğal biçimde giriyor. "Her gece 02:00'de smoke yük testi koş, p95 şu eşiği aşarsa pipeline'ı kır" düzenini k6 ile yarım günde kurarsınız.
JMeter ise bu işin emektarı. GUI'si yeni başlayan için daha erişilebilir, protokol desteği hâlâ rakipsiz: JDBC ile doğrudan veritabanına yük bindirmek, JMS kuyruklarını test etmek, FTP senaryoları koşmak gerektiğinde JMeter'e dönüyoruz. Kurumsal ortamlarda bir avantajı daha var: birçok kurumun test ekibi JMeter'i zaten tanıyor, hazır rapor formatları denetimlerden geçmiş oluyor.
Pratik kuralımız şu: API odaklı, geliştirici merkezli işlerde k6; karışık protokol, hazır raporlama ve GUI ihtiyacında JMeter. İkisini aynı projede kullandığımız da oluyor — biri CI'da nöbet tutuyor, öbürü büyük tatbikatlarda sahaya çıkıyor.
Testin en çok yalan söylediği yer: senaryo gerçekçiliği
Aracın hangisi olduğundan çok daha önemli bir konu var: senaryonun gerçek hayata benzemesi. Kaç kere gördük — ekip tek bir endpoint'e saniyede bin istek atıyor, "sistem kaldırıyor" diye rapor yazılıyor, sonra gerçek trafik altında her şey çöküyor.
Gerçek kullanıcı tek endpoint'e vurmaz. Girer, gezinir, arama yapar, durup düşünür, sepete ekler, vazgeçer, geri gelir. Aradaki o duraklamalara "think time" deniyor ve senaryodan çıkarıldığında test, gerçekte var olmayan iyimser bir tablo çizer. Çünkü eşzamanlı oturum sayısı, bellek kullanımı, oturum deposu yükü — hepsi bu bekleme desenine bağlı şekilleniyor.
İkinci şart, yük profilinin kademeli olması. Biz dört evreli bir profil kullanıyoruz: yavaş yavaş yükselen ramp-up, sabit yükte uzun bir plato, ani bir spike ve saatlerce süren soak (dayanıklılık) evresi. Her evre farklı bir hastalığı ortaya çıkarıyor — spike, otomatik ölçekleme gecikmelerini yakalar; soak ise bellek sızıntılarını. Bir lojistik müşterimizin sisteminde her şey iki saatlik testte pırıl pırıldı; sekiz saatlik soak testinde bellek sızıntısı kendini gösterdi. Üretimde bu, "her gece yeniden başlatıyoruz, sebebini bilmiyoruz" olarak yaşanıyordu.
Üçüncü şart, üretim benzeri veri. Yüz kayıtlık tabloyla yapılan test, on milyon kayıtlık gerçeği temsil etmez; sorgu planları bambaşka çalışır. Anonimleştirilmiş üretim kopyası veya aynı hacimde sentetik veri — biri şart.
Dördüncü bir şart daha ekleyeyim, sık atlanıyor: test ortamının üretime benzemesi. Üretimin yarısı kadar CPU'su olan bir sunucuda koşan test, sonuçları ancak "yorumlanarak" kullanılabilir hale getirir ve yorum, ölçümün düşmanıdır. Aynı şekilde önbellek ve CDN katmanları: soğuk cache ile yapılan ilk koşu, ısınmış sistemin performansını göstermez — biz her tatbikatta önce ısınma turu koşar, ölçümü ondan sonra başlatırız. Yük üretecinin kendisinin darboğaz olması da klasik bir tuzak; tek makineden yüz bin sanal kullanıcı üretmeye çalışıp aslında kendi laptopunuzu test ettiğinizi fark etmemek, yaşanmış bir hikâyedir (bizim değil neyse ki, ama yakından tanık olduk).
Ortalama yanıt süresi neden yalancıdır
Test koştu, rapor geldi: "ortalama yanıt süresi 180 ms." Kulağa hoş geliyor, değil mi?
Gelmesin. Ortalama, bin kullanıcının 950'sinin 100 ms, 50'sinin 8 saniye beklediği bir sistemi de "makul" gösterir. O yüzden biz ortalamayı neredeyse hiç konuşmuyoruz; p95 ve p99 yüzdelik dilimlerine bakıyoruz. p95, kullanıcıların yüzde 95'inin bundan daha hızlı yanıt aldığı süredir — en mutsuz yüzde 5'iniz orada yaşıyor ve sosyal medyaya yazan da genellikle onlar oluyor.
Yüzdeliklerin yanında üç şeyi birlikte okuyoruz: hata oranı (yük altında sessizce artan 500'ler), saturasyon (CPU, bellek, bağlantı havuzu, disk — hangisi önce doluyor?) ve throughput. Bu dördü birlikte anlamlı; tek başına hiçbiri hikâyeyi anlatmıyor. Testin amacı zaten "geçti/kaldı" damgası değil, sistemin ilk nereden kırılacağını öğrenmek. Kırılma noktasını bilen ekip, kampanya sabahı panik yerine plan yapar.
Kırılma noktası demişken, bulduklarımızın çoğunun nerede çıktığını da söyleyeyim: veritabanı bağlantı havuzu, yavaş sorgular ve dış servis çağrıları. Uygulama sunucusunu ölçeklemek kolay; ama arkadaki veritabanı tek ve havuz 50 bağlantıyla sınırlıysa, öndeki sunucu sayısını ikiye katlamak sadece kuyruğu uzatır. Bir müşterimizde tek bir yavaş rapor sorgusunun, yük altında tüm havuzu işgal edip alakasız sayfaları bile yavaşlattığını gördük — çözüm o sorguya bir index ve rapor işini kuyruğa almaktı, sunucu büyütmek değil. Yük testi işte bunu veriyor: parayı nereye harcamanız gerektiğini.
Bir kere test etmek, hiç test etmemeye benzer
Son ve bence en önemli mesele: yük testi bir etkinlik değil, süreç. Sistemi bugün test ettiniz, harika; üç ay sonra eklenen o masum görünümlü rapor sayfası, kimsenin fark etmediği bir N+1 sorgusuyla her şeyi değiştirmiş olabilir. Biz her büyük sürüm öncesi test koşuyoruz ve kritik sistemlerde hafif bir yük senaryosunu CI'a bağlıyoruz — performans gerilemesi, müşteri şikâyetiyle değil pipeline uyarısıyla haber veriyor.
Performans bir özellik değil, süreçtir. (Bu da ofiste koro halinde tamamlanan cümlelerden.)
Son bir tavsiye, raporlama üzerine: test sonuçlarını yönetime p95 grafiğiyle anlatmayın; kimsenin umurunda olmaz. "Mevcut altyapı, kampanya hedefinizdeki eş zamanlı kullanıcının şu kadarını kaldırıyor; hedefe ulaşmak için şu iki iyileştirme gerekiyor, maliyeti şu" cümlesi kurun. Teknik ölçümü iş diline çevirdiğiniz an, yük testi bütçe kaleminden sigorta poliçesine dönüşüyor — ve bir daha kimse "gerek var mı buna" diye sormuyor. TV reklamıyla çöken o site var ya; ertesi yıl aynı kampanyayı, önceden test edilmiş sistemle, tek kesinti yaşamadan geçirdi. İki yıl arayla aynı müşteri, iki farklı sabah.
Kampanya döneminiz yaklaşıyorsa ya da "bizim sistem kaç kullanıcı kaldırır" sorusunun cevabını gerçekten bilmiyorsanız, bir yazın — mevcut sisteminize dokunmadan, gerçekçi bir yük tatbikatının nasıl kurgulanacağını birlikte planlayalım. Ölçmeden bilemezsiniz; ama ölçmek, sanıldığından çok daha ulaşılabilir bir iş.