Apache JMeter

JMeter
Bir Web uygulamasının üzerinde değişik türden yükler oluşturmak için gerekli tüm özelliklere sahiptir.

JMeter ile yük testi yapabilmek için, web uygulamamızı JMeter’a aynen bir kullanıcı kullanıyormuş gibi kullandırtmamız lazımdır. Yani JMeter, uygulamamıza bağlanıp, bir kullanıcı gibi sayfaları yüklemeli, biraz veri girmeli, bir şeyler silmeli, ve uygulamadan bazı listeler almalıdır. Yani JMeter, uygulamayı
bir sanal kullanıcı gibi kullanmalıdır.
JMeter, web uygulamanıza sanal bir kullanıcı olarak gözükmek için, HTTP protokolunu kullanır. Bir JMeter’a verilen test planı, hangi sayfanın ne zaman, ve hangi bilgiyle çağırıldığını belirler. Bu bilgilerin ışığında test planını işleme koyduğunuz zaman, JMeter HTTP protokolü ile uygulamanıza bağlanacak ve istediğiniz veriler ile sayfalarınızı gezmeye başlayacaktır. Eğer test planımızı dinamik veriler girebilecek şekilde ayarlamışsak, eşzamanlı kullanıcı sayısını istediğimiz kadar arttırabiliriz, ve böylece gerçek dünya şartlarında uygulamamızın
nasıl davranacağını, nihai ortamda işleme konmadan önce, görebilmiş oluruz.

Test planı hazırlamak için, iki yöntemi takip edebilirsiniz. İlki, JMeter’a gerekli çağrı komutlarını elle eklemektir. İkincisi, siz web uygulamasını kullanırken yapılan tüm hareketlerinizi JMeter’a kaydettirmenizdir. İkinci yöntem, doğal olarak daha basittir, ve takip edilmesini tavsiye ettiğimiz yöntem budur.

JMeter’in kaydettiği test planını kullanmadan önce biraz değiştirmeniz gerekecektir, fakat bu değişiklik çok büyük ölçekte olmayacaktır, ve her şeyin elle yapıldığı şartlardan çok daha basit olacaktır.

JMeter Kullanımı
JMeter programını kurmak için JMeter sitesinden indireceğiniz zip dosyasını herhangi bir dizinde açın. JMeter ana dosyasının JMETER_DIR altında olduğunu farz edersek, progamı başlatmak için JMETER_DIR/bin/jmeter.bat ya da JMETER_DIR/bin/jmeterw.bat dosyasına tıklamamız gerekiyor. JMeter ilk başladığında aşağıdaki gibi bir ekran göreceksiniz;
                                                                                         JMeter Açılış Ekranı
JMeter’in görsel kullanımı ilk başta değişik gelebilir. JMeter da bir görsel birimi sürükle/bırak (drag/drop) ile hareket ettirip yerine bıraktığınızda, size aşağıdaki şekilde gösterildiği gibi bir menü ile bir seçim sunulacaktır.

Gösterilen örnekte, Counter adlı JMeter görsel birimini HTTP Request Defaults adlı birimin üzerine bırakmışız. Sorulan sorulardan eğer Insert Before seçilirse, sürüklediğiniz birim, üzerine bıraktığınız birim ile aynı seviyede, ama önce gelmek üzere pozisyonlanır.
                                                                                                   Sürükle ve Bırak
Insert After seçilirse, yine aynı seviyede, ama sonra gelecek şekilde pozisyonlanma yapılır. Add as Child seçilir ise, bir birim öteki birimin çocuğu olacak şekilde düzenlenir. Her birimi her başka birim altına çocuk olarak eklemek legal değildir; JMeter yeni birimi sadece çocuk kabul eden diğer birimlerin altına atmanıza izin verecektir.

Senaryo Kaydetmek
Elle ya da üretilerek girilen test planları “Test Plan” altına gitmesini isteriz. Test planını üretebilmemiz için, üzerinden uygulamamıza bağlanacağımız bir proxy servisi yaratmamız gerekiyor. Proxy servisi,Web tarayıcılarımızdan bildiğimiz bir kavramdır. Internet’te bir siteye bağlanırken, genelde o siteye direk olarak
değil, bir proxy üzerinden çıkarız, yani web isteğini bizim için bir proxy (yer tutucu) gerçekleştirmiş olur. Bir yerel ağın Internet’e bağlantısı genellikle bir proxy üzerinden yapılır, mesela bir şirketin yerel ağından dışarı çıkan herkes, aynı proxy’i kullanır. Ağ güvenliği için bu şekilde bir kullanıma ihtiyaç vardır.


JMeter da, aynen yerel ağ için hazırlanan bir proxy gibi, bir proxy başlatabilir. Bunu yapma amacı, o proxy üzerinden web uygulaması test edilirken, yapılan tüm hareketleri, GET, POST işlemlerini gözlemleyebileceği bir geçiş noktasına ihtiyacının olmasıdır. Yani birazdan hazırlamasını öğreneceğimiz JMeter Proxy
Server, biz testimizi yaparken tüm web isteklerinin ve cevaplarının üzerinden yönlenlendirileceği bir geçiş noktası olacak.

Proxy Server eklemek için,Workbench üzerinden sağ tıklama yaparak menüden Add Non-Test Elements
HTTP Proxy Server seçeneğini seçin;
                                                     JMeter ˙Için Proxy Server Yaratmak

Proxy’nin ayarlarını değiştirmek için, eklenen HTTP Proxy Server biriminin üzerinde tıklayarak, ayarlarını yapabiliriz. Mesela Proxy Server’in hangi port üzerinden servis vereceğini tanımlamak istiyorsak, o port numarasını Port kutusundan girmeliyiz. Genelde, yerel bir JBoss’ta çalışan uygulamanın port numarası 8080 olacağı için, Proxy Server için verilen olağan değeri 8080’i değiştirmemiz gerekiyor. Bu değer için 8090 kullanalım. Aşağıdaki resimde bu ayarları görebiliriz.

Değişecek diğer ayar, Target Controller için “Use Recording Controller” ve Grouping altında “Store 1st sample of each group only” seçenekleridir. Bu seçeneklerden Target Controller, kaydedilen kullanıcı işlemlerinin “nereye kaydedileceğini” belirler. Biz bu kaydedilme işleminin Test Plan altında bir dinleyici tarafından dinlenip kaydedilmesini istiyoruz. Böylece test planımız, dinleme ve kaydetme bittikten sonra bizim için işletilmeye hazır bir test planını aynı JMeter penceresi içinde bekletiyor olacaktır.
                                                                                                  Proxy AyarlarıÖnce test planının kullanıma hazır bir hˆale getirmemiz gerekiyor. Ayarları öyle yapalım ki, test plan üretimi bittikten sonra, üzerinde ufak değişikliklerden sonra “İşlet” komutunu verebileceğimiz bir yapı hazır olsun. Bunun için öncelikle eklememiz gereken, Thread Group birimidir. Bu birim, yük testlerinin kaç Thread ve kaç kere işletileceğini kontrol eden bir birimdir. Thread Group eklemek için, Test Plan üzerinden sağ tıklama ile Add Thread Group seçimini yapın.

Test planının hangi makinaya ve porta bağlanacağını kontrol edebilmek
için, Http Request Defaults adında “her sayfa bağlantısı için aynı” olacak olağan değerleri belirleyen bir birim eklemeliyiz. Bu eklemeyi, biraz önce ekledi ğimiz Thread Group üzerinden Add Config Element HTTP Request Defaults seçimi ile yapabiliriz. Ekleme bittikten sonra JMeter ekranı aşağıdaki resimdeki gibi gözükecektir.

HTTP Request Defaults değerleri şimdilik localhost, 8080 ve http olabilir. Kullanıcıyı kayıtlamayı localhost:8080 üzerindeki bir uygulama üzerinden yapacağımız için, testi geri çalarken (replay) aynı makina ve port değerini kullandık. Eğer kaydedilmiş testleri başka bir makina, port’a doğru yönlendirmek istersek, bunun için test edilecek makinayı değiştirmek için HTTP Request Defaults üzerinden çok basit bir işlem olacaktır. Zaten klasik JMeter kullanma kalıbı budur: Yerel bir JBoss üzerinde test hareketleri kaydedilir, daha sonra, daha güçlü bir test makinası üzerinde aynı testler geri çalınır.

Şimdi kayıt edici birimi ekleyelim: Thread Group altında Add Logic Controller Recording Controller ile bir kayıt edici eklemiş oluruz. Kayıt edici için hiçbir ayar yapmamız gerekmiyor. JMeter için tek önemli olan kayıt edicinin nerede olduğudur çünkü kayıt edilecek sayfa istekleri o seviyeye yazılacaktır.

                                                                            HTTP Request Defaults Ayarları
Kayıt etmeye başlamadan önce yapmamız gereken son işlem, Internet tarayıcımızın üzerinden geçiş yapacağı Proxy Server bilgisini vermektir. Bu Proxy Server, JMeter’da tanımladığımız Proxy Server olacak. Mozilla Firefox üzerinde proxy değiştirmek için Tools Options Connection Settings ekranına gidin, ve HTTP Proxy değeri için localhost ve 8090 girin. Bu değerler, biraz önce JMeter Proxy Server için tanımladığımız değerlerin aynısıdır. Ve dikkat edin ki No Proxy For kutusunda localhost olmasın. Internet Explorer için ise, Tools
Internet Options Connections LAN Settings altındaki Proxy Server ekranında “Use a proxy server” kutusunu seçin ve, Address ve Port kutularına gerekli değerleri girin. Aşağıdaki şekil üzerinde Mozilla proxy ayarlarını görüyoruz.

Artık kaydetmeye hazırız. Şimdi kayıt için şunları yapalım;
• Web uygulamamızı başlatalım
• JMeter’da tanımladığımız HTTP Proxy Server ekranındaki Start düğmesine
basarak, proxy server’ı başlatalım.
• Tarayıcımızı localhost:8080’a yönelterek, uygulamımızı test etmeye başlayalım.
Test uygulaması olarak örnek kodlar içindeki StrutsHibAdv projesini kullandık. Bu uygulamanın tam adresi http://localhost:8080/kitapdemo/¬main.do adresidir. Bu adrese ilk gittiğimiz zaman, ilk ekran yüklemesi ile
arka planda birçok işlemin yapıldığını göreceksiniz. Web isteği, tarayıcı proxy server’ı üzerinden Web uygulamamıza gidecek ve gözlemi yapan proxy server JMeter olduğu için, yaptığımız istek JMeter tarafından yakalanacaktır. Web isteği, JBoss üzerindeki uygulamaya yönlendirilir, ama ondan önce JMeter bu
                                                                              Mozilla Firefox i¸cin Proxy Ayarlarıisteğin ne olduğunu Test Plan altında kaydedecektir (çünkü Recording Controller’ı orada tanımladık). Web isteği işini bitirip geri gelir gelmez, Thread Group Recording Controller altında yeni birimlerin otomatik olarak eklendi ğini göreceksiniz. S¸ekil 5.8 üzerinde kaydedilen işlemleri görüyoruz. Bu işlemler, şu web isteklerinden üretilmiştir;
• Ana ekrana git
• Yeni bir araba ekle (araba #1)
• Bir yeni araba daha ekle (araba #2)
• Araba #1’i sil
• Araba #2’yi yeni bilgilerle güncelle
• Garage listesi al
• Garage #2 üzerine tıklayarak altındaki arabalara bak
• Tüm araba listesini “Liste” seçeneğine tıklayarak göster


Bir senaryoyu kaydettikten sonra onu File Save Test Plan as menü seçeneği ile disk’e yazabilirsiniz.
                                                                                             Kaydedilen İşlemler

Kaydedilen Testleri İşletmek
Kayıt edilen web isteklerinin detaylarını, o isteğin üzerine tıklayarak görebilirsiniz. Mesela /kitapdemo/add-car.do isteğine tıklarsak, bu istek içinde hangi parametrelerin gönderilmiş olduğu sağdaki detay ekranında listenecektir. add-car.do için Send Parameters With the Request başlığının altında, licensePlate,
available ve size gibi, bir araba yaratmak için gerekli parametrelerin FORM içinde gönderilmiş olduğunu görüyoruz. Herşey düzgün gözüküyor.

Not: Bir tek detay haricinde her şey düzgün; Kayıt işlemindeki tek eksik, /kitapdemo/update-car.do içindeki version bilgisinin kayıt edilmemesidir. Bu bilgiyi, o isteğin detayına girip, Add düğmesine
tıklayarak elle ekleyebilirsiniz. Version değeri için 0 değerini girin (version konusunun detayları için 3.8.3 bölümüne bakabilirsiniz). Kayıt işlemi tamamlandığına göre, senaryomuzu kurumsal uygulamamız üzerinde işletebiliriz. Veri tabanındaki tüm car satırlarını temizledikten sonra (yoksa aynı licensePlate kimlikli eklenen ikinci car problem çıkartırdı) test senaryosunu JMeter ana menüsü Run | Start ile işletelim. Senaryo, Thread Group içinde tanımlanan işletme koşullarına göre işletilecektir. Bu koşullar tek bir thread’in sadece bir kez işletilmesini öngörüyor. Bu ayarlar, Thread Group detay ekranında gözükebilir.
                                                                                             Thread Group Detayı
  Thread Group ekranındaki seçenekleri daha detaylı tarif etmemiz gerekirse:
• Number of Threads: Yük testinin eşzamanlı kaç thread ile işletilmesi gerektiğini kontrol eder.
Ramp-up Period: Number of Threads seçeneğinde belirtilen kadar thread’in, ne kadar süre içinde başlatılması gerektiğini buradan ayarlayabilirsiniz. Mesela eğer thread sayısı 10 ve Ramp-Up Period 100 ise,
100 tane thread, 10’ar saniye aralıklarla başlatılacaktır. Eklemek gerekir ki biz yük test senaryolarımızda bu seçeneği pek kullanmıyoruz. Bunun sebebi, eşzamanlı aktif sanal kullanıcı sayısının sürekli belli bir sayıda tutacak türden testlere ihtiyaç duymamızdır. Bu bilinen sayı kadar bir yük oluşturulması, uygulamamızın eşzamanlı kaç tane kullanıcıya dayanabileceği hakkında bize bir fikir vermektedir.
Loop Count: Number of Threads’de belirtilen kadar thread’in kaç kere arka arkaya işletileceği buradan ayarlıyoruz. Meselˆa 10 thread’e Loop Count 5 verdiysek, uygulamamız üzerinde toplam 50 thread işlemiş olacaktır (tabii herhangi bir anda, uygulama üzerinde eşzamanlı sadece 10 thread olacaktır).

Değişken (Dinamik) Test Değerleri
Test planımızı bir kere işlettiğimize göre, aynı planı, eşzamanlı birçok kullanıcı (thread) tarafından ve üstüste işletmeyi düşünebiliriz. Fakat bunun için Thread Group altındaki muhtelif alanları değiştirip tekrar işleterek doğru sonuç alacağımızı düşünüyorsak, yanılırız. Eğer senaryoyu bu şekilde işletirsek, Hibernate ve veri tabanı tarafından hatalar geldiğini göreceğiz.
Bu hataların sebebi, birden fazla Car nesnesinin aynı kimlik ile birkaç kere eklenmeye çalışılıyor olmasıdır. Bu da, test senaryosunun statik yapısı gözönüne alınırsa, çok normaldir. Test senaryomuz, test içinde gömülü (hard coded) bir licensePlate verisini kullanarak yazıldı. Eğer aynı testi birkaç thread’den işletirsek, aynı licensePlate’li arabalar, birkaç kez eklenmeye çalışılacaktır, ve bu da license_plate kolonu tekil olması gereken car tablosu için hatalı bir durumdur!
O zaman, eşzamanlı birçok kullanıcıyı aynı test senaryosu ile kullanmak istiyorsak, senaryomuza dinamik bir licensePlate kullandırabilmemiz gerekiyor. Öyle ki, senaryoyu işleten her thread, otomatik olarak yeni bir licensePlate kullanıyor olsun.

Counter
Senaryomuza bu şekilde bir dinamikliği JMeter programının Counter tekniğini kullanarak ekleyebiliriz. Bir Counter, birim olarak eklendiği Thread Group altıda, her değişik thread’in her döngüsünde yeni artacak şekilde tanımlanabilen bir JMeter birimidir. Bu birimi, Recording Controller üzerinden Add | Pre Processors | Counter seçeneği ile ekleyebiliriz.
                                                                              Counter

Counterin hangi sayıdan başlayıp kaçar kaçar artacağını ayarlamak için,
Counter üzerinde tıklayarak detaylarına girebiliriz. Örnek için bizim girdiğimiz değerler aşağıdaki şekilde gösterilmiştir.

                                                                             Counter ile Artan Plaka Değişkeni
Bu ayarlara göre Counter, 1 değerinden başlayarak birer birer artacak, ve 10000 üst değerine kadar böyle artacaktır.

Artık elimizde dinamik, değişken bir licensePlate değişkeni olduğuna göre, bu değişkeni gereken web istekleri içinde kullanabiliriz. Mesela, elimizde iki tane add-car.do isteği var, bir istek için \${licensePlateCounter}-1, öteki için \${licensePlateCounter}-2 tanımını kullanırsak, bu istekleri arka arkaya işletebilmiş olacağız (licensePlateCounter dinamik bir değişken olmasına rağmen, bir tur bitmeden değişmez, bu sebeple aynı tur içinde iki farklı Car için aynı değişkeni kullanmak, yine bir hataya sebep olurdu. O yüzden aynı tur içinde licensePlateCounter’ı her araba için ufak bir ek ile değiştiriyoruz).
Dinamik licensePlate kullanan diğer yerler şunlardır (ve bunların hepsini licensePlateCounter kullanacak şekilde değiştirmemiz gerekiyor).
Test silme işlemi için biraz önce eklenen licensePlateCounter değişkenlerinden birini seçip, silme detayına girip FORM içinde gönderilen parametrelerden licensePlate için bu değişkeni (mesela \${licensePlateCounter¬}-1) girebiliriz. Böylece eklenen arabalardan biri silinmiş olacaktır.
edit-car.do: Yükleme testi içindeki licensePlate’i değiştirin (silinmemi ş olan Car için)
update-car.do: Biraz önce yüklenen Car’ın güncellenmesi için, license-Plate’i değiştirin. Ayrıca, description öğesinin, yine licensePlate-Counter’ı kullanarak, dinamik bir değer göndermesini sağlayın. Bunun sebebi, eğer bir nesne üzerinde hiçbir değişiklik olmazsa, Hibernate’in bu durumu anlayıp (dirty check), veri tabanında UPDATE yapmayacak olmasıdır (Hibernate ne kadar akıllı değil mi?). Biz testimizde bir veri tabanı güncellemesi olmasını istediğimiz için, herhangi bir değerin “değişmesini” zorlamak istiyoruz. Bu yüzden description öğesi için “description changed for \${licensePlateCounter}” gibi bir ibare kullanabilirsiniz.
                                                                             Dinamik Plaka Değeri ile add-car.do
Bu değişikliklerden sonra, test senaryomuzu artık birden fazla thread ve birden fazla kere işletmemiz mümkün olacaktır. Tam bir yük testi!


Veri Hazırlık İşlemleri
Test senaryomuzu işletmeden önce, her seferinde, veri tabanını elle temizlemek gerekiyor. Bu çok külfetli bir işlemdir (Kural #7). Evet, Counter kullanımı ile her işleyiş içinde değerler değişiyor, ya da Randomizer kullanımı ile işleyişten işleyişe bile değişik değerler almamız mümkün, fakat senaryo sonunda her Car’ı silen bir web isteğimiz olmadığı için, veri tabanında bazı car satırları artık kalmış olacaktır. Eğer her senaryonun temiz bir veri tabanı ile başlamasını istiyorsak, ve eğer silme işlemini elle yapmak istemiyorsak, bu işi JMeter’a yaptırabiliriz. JMeter’ın programlama birimlerinin arasında, bir JDBC sorgu işletme birimi de vardır. Bu birime verilen tanıdık, bildik JDBC bağlantı ayarları üzerinden işletilecek bir sorgu sayesinde her test senaryosunun
başında truncate table car ile tabanın temizlenmesini sağlayabiliriz.

 JDBC birimini yeni bir Thread Group altına koymamız gerekiyor, çünkü senaryomuzu işleten esas Thread Group’u, eşzamanlı ve birden fazla işleyebilecek şekilde hazırlanmış bir gurup idi. Her thread için veri tabanı temizliği yapılmasını istemiyoruz, temizliğin sadece bir kez, ve test başında yapılmasını istiyoruz. O
zaman başa yeni bir Thread Group ekleyebiliriz, ve “thread sayısı” ve “kaç kere” parametrelerini 1 değerinde tutarız.
Bu yeni gurup üzerinde Add | Config Element | JDBC Database Login Defaults adında yeni bir birim ekleyelim. Veri taban bağlantı bilgilerini buradan gireceğiz. Örnek bir ekranı aşağıdaki şekil üzerinde görebilirsiniz.

Bağlantı ayarları tamamlandıktan sonra, işletmek istediğimiz sorguyu girebiliriz. Bunun için ikinci bir JDBC birimi olan JDBC Request birimini kullanaca ğız. Aynı Thread Group altında Add | Sampler | JDBC Request ile bu birimi ekleyebiliriz. Temizlik sorgumuzu işletmek için de, birimin detaylarına girip SQL Query String parametresi için truncate table car değerini girebiliriz. JDBC ayarlarının bitmiş halini aşağıdaki şekil üzerinde görebilirsiniz.

Not: JMeter’in JDBC ile veri tabanınıza erişebilmesi için, gerekli JDBC sürücü jar dosyasına ihtiyacı vardır. Bu dosyayı geliştirme dizininden alıp (mesela MySQL için mysql-connector-java-3.0¬.16-ga-bin.jar dosyası) direk JMETER_DIR/lib altına atabilirsiniz.
                                                                  JDBC Bağlantı Ayarları

                                                                                               JDBC Sorgu Tanımı


Tüm bunlar yapıldıktan sonra, artık Run | Start ile senaryomuzu istediğimiz kadar thread ile ve istediğimiz kere üst üste çalıştırmamız mümkün olacaktır.


Komut Satırından Çalıştırmak
Eğer JMeter programını görsel arayüzü yerine komut satırından çalıştırmak istiyorsanız, önceden disk’e kaydettiğiniz senaryoyu File | Open ile tekrar yüklemek yerine, bir senaryoyu kaydedildiği şekliyle direk komut satırından jmeter komutunu -n seçeneği üzerinden kullanarak işletebilirsiniz. JMETER/¬ bin dizini PATH içinde ise şu komutu kullanmak yeterlidir;
jmeter -n -t myscenario.jmx

Performans Verisini Görmek
Yük testinin işlerken ne kadar zaman aldığını görmek için, görsel bir rapor birimi de eklemek mümkündür. Thread Group üzerinden Add | Listener | Aggregate Report seçilirse, raporlama birimi eklenmiş olacaktır.
                                                                Yük Testi Sonuçlarını Görmek

Yukarıdaki şekil üzerinde görülen sonuçlar, yerel bir makina üzerinde 10 eşzamanlı thread’in 5 kere arka arkaya işletilmesi sonucunda elde edilmiştir. Test makinasının yerel olması, loglama seviyesinin DEBUG olması ve StrutsHibAdv projesinin üzerinde optimizasyon yapılmamış (şimdilik) bir proje olması sonucunda, 1 saniyede 2.6 işlem gerçekleştirilebilmiştir.

2 yorum:

  1. jmeter'ın menülerini ayrı ayrı anlatma ve bu programı yeni kullancaklara tiyolar üzerine post hazırlama şansımız var mı?

    YanıtlaSil
  2. JMeter kendi içinde ayrı bir dünya. Onu kullanmak, tariflemek oldukça emek ve sabır isteyen bir uygulama. Bununla ilgili piyasada birkaç kitap dahi olması lazım. Çok yoğun olduğum şu günlerde böyle bir çalışmayı maalesef hayata geçiremeyebilirim. Onun yerine piyasadaki mevcut kaynakları incelemenizi öneririm Yalnız Kurt.
    İyi Testler

    YanıtlaSil