~/Ali GÖREN

.NET Ekosistemi İçin Dağıtık Yük Testi Framework’ü: NBomber

Ali Goren · · 6 dk okuma

Görsel LinkedIn ile oluşturulmuştur.
Bir yazılımın belirli yükler altında nasıl davrandığını anlamak için performans testleri kritik öneme sahiptir. Sistemde artan kullanıcı sayısı ile birlikte sistemlerin ölçeklenebilir olup olmadığı da önemli hale gelmiştir. Özellikle mikroservis mimarilerinin yaygınlaşması ve dağıtık sistemlerin artışıyla yük testi yapılabilecek araçlara da ihtiyaç artmaya başlamıştır. Bu ihtiyaçlar için de aşağıdaki araçlar ortaya çıkmıştır

Bu sistemler dışında, bu yazının da konusunu oluşturan NBomber da yine yük testi yapabilmenize olanak sağlayan F# ile geliştirilen, .NET ekosisteminde kullanılabilecek faydalı bir framework olarak öne çıkıyor.

NBomber - Distributed load testing framework for .NET/C#/F#

NBomber Nedir?

NBomber yük testleri ve stres testleri yapmak için geliştirilen, açık kaynak kodlu ve .NET tabanlı bir performans test aracıdır. Her ne kadar açık kaynak kodlu olsa da lisans politikası onu kişisel kullanım için ücretsiz kılarken, ticari lisanslar için ücret talep etmekte.

NBomber henüz cloud ortamda bir desteğe sahip olmasa da yakın zamanda geleceğini web sitelerinde de görebilirsiniz. Ayrıca bu kısımda mevcut lisans ücreti politikasını da görebilirsiniz.

NBomber’ın Öne Çıkan Özellikleri Nelerdir

✅ Platform Bağımsız Çalışabilme

.NET Core tabanlı olduğı için herhangi bir sisteme bağımlı olmak zorunda değilsiniz. Ayrıca dockerize etmek de çok basit. Özellikle Visual Studio ya da Rider gibi IDE’ler kullanıyorsanız bu daha da basit halde.

✅ Zengin Protokol Desteği

NBomber, sadece HTTP testleri yapmak için tasarlanmış gibi durabilir ancak bunun dışında WebSockets, gRPC, Kafka, AMQP, SQL gibi protokollerde de testler yapmanıza olanak sağlar.

✅ Esnek API Desteği

NBomber dokümanlarında da göreceksinizdir ama buradan da belirtmek isterim, dilediğinizde kendi Sinklerinizi yaratabilmeniz için geliştirici dostu bir API mevcut.

✅ Gelişmiş / Görsel Raporlama

NBomber’da dilerseniz test sonuçlarını JSON, CSV ya da HTML olarak alabilirsiniz. Örnek bir rapor aşağıda yer almaktadır.

https://nbomber.com/assets/reports/html_report.html

Bunun dışında gerçek zamanlı olarak da raporlama yapabilmek için aşağıdaki sinkler desteklenmektedir;

  • InfluxDB
  • TimescaleDB
  • Grafana

Bu bahsettiğim sinkler’i kendiniz de geliştirebilirsiniz. Bunun dışında bir veri tabanında tutmak istiyorsanız da yine kendi implementasyonunuzu yapabilirsiniz.

✅ Dağıtık Cluster Desteği

NBomber, dağıtık cluster desteği sağlar. Distributed mode’da milyonlarda kullanıcı varmış gibi simultane testler yapabilirsiniz. Bunu yine bahsettiğim gibi cluster ile yapabilirsiniz.

Overview | NBomber

✅ CI/CD Entegrasyonu

Testlerinizi otomatik olarak çalıştırmak için CI/CD pipelinelarınıza NBomber’ı ekleyebilirsiniz. Olası performans düşüşlerini yakalayabilmek için assertion ve thresholdlar tanımlayabilirsiniz. Kendi örnekleri şu şekilde;

NBomber/examples/xUnitExample/LoadTestExample.cs at dev · PragmaticFlow/NBomber

Aslında burada xUnit ya da NUnit gibi testler içerisinde de NBomber’ı kullanabilirsiniz. Detaylı bilgi şurada yer almaktadır;

Asserts and Thresholds | NBomber

NBomber ile Örnek Yük Testi Uygulaması

Bu kadar çok detay verdik ancak NBomber nasıl istediğimiz işleri yapar onu henüz konuşmadık.

NBomber temelde, senaryolardan oluşur ve bu senaryolar da kendi içerisinde adımlara sahiptir. Adımları da kullanıcı davranışı olarak düşünebilirsiniz. Örnek senaryolarımızda bu hareketleri tek bir kullanıcının yaptığını da düşünebilirsiniz. Kodlamayı yaparken de bunu göreceğiz. Ama önce NBomber’ı projemize dahil edelim.

dotnet add package NBomber

Projemizi oluşturduğumuzu varsaydığım için direkt yukarıdaki komutla dahil ettim. Şimdi ilk senaryomuzu oluşturalım.

using var httpClient = new HttpClient();
var ilkSenaryo = Scenario.Create("httpbin_ilk_test", async context =>
{
    var response = await httpClient.GetAsync("https://httpbin.org/get");

    return response.IsSuccessStatusCode ? Response.Ok() : Response.Fail();
}).WithLoadSimulations(Simulation.KeepConstant(10, TimeSpan.FromSeconds(30)));

NBomberRunner
.RegisterScenarios(ilkSenaryo)
.Run();

Bu örnekte httpbin adresine, 10 sanalkullanıcıyla sabit olarak 30 saniye boyunca istek atıyoruz. Burada örnek çıktı şöyle oluyor

scenario: httpbin_ilk_test
  - ok count: 1624
  - fail count: 0
  - all data: 0 MB
  - duration: 00:00:30

load simulations:
  - keep_constant, copies: 10, during: 00:00:30

┌─────────────────────────┬─────────────────────────────────────────────────────────────┐
│                    step │ ok stats                                                    │
├─────────────────────────┼─────────────────────────────────────────────────────────────┤
│                    name │ global information                                          │
│           request count │ all = 1624, ok = 1624, RPS = 54.1                           │
│            latency (ms) │ min = 135.86, mean = 182.28, max = 1118.07, StdDev = 121.53 │
│ latency percentile (ms) │ p50 = 140.29, p75 = 141.57, p95 = 449.28, p99 = 748.03      │
└─────────────────────────┴─────────────────────────────────────────────────────────────┘

Burada basit bir senaryo tanımını gördük. LoadSimulation tanımı ise yine en basitlerinden birisiydi. Diğer simülasyon türleri aşağıda yer almaktadır;

Load Simulation | NBomber

Biz yine de açıklayalım.

KeepConstant

Sabit sayıda sanal kullanıcıyı belirli bir süre boyunca çalıştırır. Örneğin, 10 kullanıcı 30 saniye boyunca sürekli test isteği gönderir.

Inject

Her saniyede belirli bir sayıda yeni kullanıcı başlatır. Örneğin, her saniye 5 yeni kullanıcı başlatılır ve 30 saniye boyunca çalıştırılır.

RampConstant

Kullanıcı sayısını belirli bir süre boyunca kademeli olarak artırır. Örneğin, ilk başta 1 kullanıcıyla başlar, sonra yavaşça 50 kullanıcıya çıkar.

RampInject

İstek oranını (TPS — Transactions Per Second) kademeli olarak artırır. Örneğin, ilk başta her saniye 1 istek atılır, sonra giderek artar.

InjectRandom

İstek oranını belirli bir aralıkta rastgele değiştirerek gönderir. Örneğin, bir saniyede 1 ile 10 arasında değişen sayıda istek gönderir.

IterationsForConstant

Belirli bir kullanıcı sayısını sabit tutarak, her bir kullanıcının belirlenen toplam iterasyon sayısına ulaşana kadar testin devam etmesini sağlar.

IterationsForInject

Belirli bir hızda (rate) yeni kullanıcılar (sanal kullanıcılar) başlatarak, toplam belirlenen iterasyon sayısına ulaşana kadar testi devam ettirir.

Pause

Bir senaryonun belirli bir süre boyunca duraklatılmasını sağlar.
Bu, senaryonun başlamasını geciktirmek veya çalışma sırasında bir ara vermek için kullanılabilir.

Burada bahsedilen simülasyon ayarları istenirse appsettings dosyasında da yer alabilir.

Load Simulation | NBomber

Konudan uzaklaşmadan son olarak da step tanımlarını görelim.

using var httpClient = new HttpClient();
var ilkSenaryo = Scenario.Create("httpbin_ilk_test", async context =>
{
    await Step.Run("sadece_get_requesti", context, async () =>
    {
        var response = await httpClient.GetAsync("https://httpbin.org/get");

        return response.IsSuccessStatusCode ? Response.Ok() : Response.Fail();
    });

    await Step.Run("query_string_ile_get_requesti", context, async () =>
    {
        var response = await httpClient.GetAsync("https://httpbin.org/get?kullaniciadi=ali");

        return response.IsSuccessStatusCode ? Response.Ok() : Response.Fail();
    });

    return Response.Ok();

})
.WithLoadSimulations(Simulation.KeepConstant(10, TimeSpan.FromSeconds(30)));

NBomberRunner
.RegisterScenarios(ilkSenaryo)
.Run();

Stepler için kullanıcı davranışlarını tanımlarız demiştim. Bu örnek uygun olmasa da nasıl tanımlandığını görmek açısından iyi olabilir.

Birden fazla step arasında veri paylaşımı yapılabilir. Bu işlemler şöyle yapılabilir;

  • ResponseType ile
  • ScenarioContext.Data ile
  • Closure Variable ile

Üç şekilde de veri paylaşabilirsiniz. Şu an için bu yazıda böyle bir örnek göstermeyeceğim. Yukarıdaki senaryoyu çalıştırınca aşağıdaki çıktıyı alıyoruz. Bu sefer örneğin ekran görüntüsünü atacağım.

Size ek olarak bazı linkler de paylaşacağım. Bunlardan birisi NBomber Studio. Kısacası çalışan testler grafik arayüzü ile görebileceğiniz bir web tabanlı arayüz.

NBomber Studio

Overview | NBomber

Aslında burada yer alan link bu arayüzü gösteriyor.

NBomber

Raporlar

Eğer varsayılan olarak bir klasör tanımı yapmadıysanız raporlarınız, uygulama dizini altındaki reports klasörüne kayıt ediliyor. Bu bilgiyi de şöyle veriyor

22:33:23 [INF] Reports saved in folder: "D:\Tests\ConsoleApp4\ConsoleApp4\reports\2025-02-02_19.32.04_session_85af8b5e"

Bu klasörün içeriği de şöyle oluyor

Örneğin steplerle beraber son oluşan testimiz için HTML rapor çıktısı şu şekilde yer alıyor

Hepsi bu kadardı. Okuduğunuz için teşekkür ederim. Umarım sizlere faydalı olabilecek bir paylaşım olmuştur.

Kaynaklar