Locust – Açık Kaynak Kod Load Test Uygulaması

Locust, web uygulamaları üzerinde detaylı olarak stress test yapabilmeye olanak sağlayan açık kaynak kodlu çok güzel bir yazılım. Temel olarak yük testinin yapılacağı web uygulaması için hangi sayfalarda kaç kişinin gezeceğini, hangi sayfalardan hangi sayfalara geçileceği, toplam dolaşım süresinin ne olacağı vs. gibi detaylı senaryonuzu bir python scripti şeklinde tarif edip, locust’a bu senaryoyu simule etmesini söylüyorsunuz.

Aşağıdaki gibi güzel ve anlaşılır bir web arabirimi olan Locust aynı anda milyonlarca anlık ziyaretiçiyi belirlediğiniz eşik değerlerine göre web uygulamanıza dolduruyor ve arayüz üzerinden uygulamanızın kullanıcı isteklerine verdiği cevapların stabilitesini ölçüp sınırlarınızı tespit edebiliyorsunuz.

Locust dağıtık yapıda çalışabilen bir uygulama olduğu için load testleri yaptığınız node’ları kolayca cluster olarak çalıştırabiliyorsunuz. Bu nedenle milyonlarca kullanıcı aktivitesini simule etmeniz mümkün oluyor. Ayrıca, web uygulamaları dışında da load testlerde kullanabilmek ve esnetilebilir olması da oldukça güzel özellikleri.

Kurulumu ve bir kaç satır python kodu ile kolayca senaryo oluşturabildiğinizden dolayı da epey kullanışlı. Yazının devamında kurulumu nasıl yapabileceğinizden ve basit bir test senaryosunun nasıl yazılıp nasıl çalıştırılabileceğinden bahsedeceğim.

Kurulum

Ben kurulumu CentOS 7.0 bir sistemde pip üzerinden gerçekleştireceğim. Bu açıdan farklı bir dağıtım kullanıyorsanız da sisteminizde pip olması kurulum için yeterli olacaktır.

CentOS sistemlerde pip paketi EPEL reposunda bulunduğundan öncesinde bu depo’yu sisteme ekleyelim:

# rpm -Uvh http://repo.boun.edu.tr/epel/7/x86_64/e/epel-release-7-5.noarch.rpm

Sonra da gcc, pip ve diğer bağımlılık paketlerini kuruyoruz:

# yum install python-pip gcc python-devel

Ardından pip üzerinden locust kurulumu yapalım:

# pip install locustio

Bu şekilde kurulum tamamlanacaktır.

Uygulama bir çok tcp connection açacağı için sunucunun limitlerini arttıralım:

# echo "fs.file-max= 100000" >> /etc/sysctl.conf
# echo "* hard nofile 40096" >> /etc/security/limits.conf
# echo "* soft nofile 40096" >> /etc/security/limits.conf
# sysctl -p

Şimdi, locust kullanmaya hazır durumda.

Temel Kullanım

Uygulamanın help menüsüne –help switch’i ile erişebilirsiniz:

Options:
  -h, --help            show this help message and exit
  -H HOST, --host=HOST  Host to load test in the following format:
                        http://10.21.32.33
  --web-host=WEB_HOST   Host to bind the web interface to. Defaults to '' (all
                        interfaces)
  -P PORT, --port=PORT, --web-port=PORT
                        Port on which to run web host
  -f LOCUSTFILE, --locustfile=LOCUSTFILE
                        Python module file to import, e.g. '../other.py'.
                        Default: locustfile
  --master              Set locust to run in distributed mode with this
                        process as master
  --slave               Set locust to run in distributed mode with this
                        process as slave
  --master-host=MASTER_HOST
                        Host or IP address of locust master for distributed
                        load testing. Only used when running with --slave.
                        Defaults to 127.0.0.1.
  --master-port=MASTER_PORT
                        The port to connect to that is used by the locust
                        master for distributed load testing. Only used when
                        running with --slave. Defaults to 5557. Note that
                        slaves will also connect to the master node on this
                        port + 1.
  --master-bind-host=MASTER_BIND_HOST
                        Interfaces (hostname, ip) that locust master should
                        bind to. Only used when running with --master.
                        Defaults to * (all available interfaces).
  --master-bind-port=MASTER_BIND_PORT
                        Port that locust master should bind to. Only used when
                        running with --master. Defaults to 5557. Note that
                        Locust will also use this port + 1, so by default the
                        master node will bind to 5557 and 5558.
  --no-web              Disable the web interface, and instead start running
                        the test immediately. Requires -c and -r to be
                        specified.
  -c NUM_CLIENTS, --clients=NUM_CLIENTS
                        Number of concurrent clients. Only used together with
                        --no-web
  -r HATCH_RATE, --hatch-rate=HATCH_RATE
                        The rate per second in which clients are spawned. Only
                        used together with --no-web
  -n NUM_REQUESTS, --num-request=NUM_REQUESTS
                        Number of requests to perform. Only used together with
                        --no-web
  -L LOGLEVEL, --loglevel=LOGLEVEL
                        Choose between DEBUG/INFO/WARNING/ERROR/CRITICAL.
                        Default is INFO.
  --logfile=LOGFILE     Path to log file. If not set, log will go to
                        stdout/stderr
  --print-stats         Print stats in the console
  --only-summary        Only print the summary stats
  -l, --list            Show list of possible locust classes and exit
  --show-task-ratio     print table of the locust classes' task execution
                        ratio
  --show-task-ratio-json
                        print json data of the locust classes' task execution
                        ratio
  -V, --version         show program's version number and exit

Kullanım şekliyle ilgili tüm bilgiyi yukarıdaki help çıktısından alabileceğiniz gibi en basit hali ile bir web sunucusunda load test yapmak için aşağıdaki şekilde bir python betiği hazırlayalım: (Akabinde betik içerisindeki direktiflerin anlamlarını söyleyeceğim.)

from locust import HttpLocust, TaskSet, task
class UserBehavior(TaskSet):

    @task(5)
    def index(self):
        self.client.get("/")

    @task(4)
    def profile(self):
        self.client.get("/sayfa1/")

    @task(3)
    def category(self):
        self.client.get("/kategori/sayfa2/")

    @task(2)
    def red5(self):
        self.client.get("/sayfa3/")

    @task(1)
    def backtrack(self):
        self.client.get("/sayfa4/")

class WebsiteUser(HttpLocust):
    task_set = UserBehavior
    min_wait=5000
    max_wait=9000

Bu tarifte, locust’a stress testinin yapılacağı web uygulamasının anasayfa, /sayfa1, /kategori/sayfa2, /sayfa3 ve /sayfa4 olmak üzere beş farklı bölümüne GET requesti yapılmasını ve simule edilen her bir kullanıcının her diğer task’e geçiş için minimım 5000 maksimum 9000 milisaniye süre beklemesini söylüyoruz. Bir başla deyişle, uygulamanızı ziyaret eden kişilerin sayfalarda geçireceği süre belirlenmiş oluyor.

Şimdi bu betiği test.py ismi ile kaydedelim ve locust’u aşağıdaki gibi çalıştıralım:

# locust -f test.py -H http://www.stresstesiyapilacakuygulama.com

Bu komutu çalıştırdığınız zaman, locust tcp 8089. portu dinlemeye başlayacak ve web tabanlı stress test uygulamasını start edecektir. Bu uygulamaya erişmek için, bir browser açık http://ip-adresiniz:8089 derseniz aşağıdaki gibi bir ekran gelecektir.

Bu ekranda ne kadar bir süre içerisinde sisteme ne kadar kullanıcının gireceğini belirtebiliyorsunuz.
“Number of users to simulate” parametresi toplamda kaç kullanıcı ile simulasyon yapacağınız, Hatch rate (users spawned/second) ise ne kadar bir sürede sisteme yeni kullanıcı dahil edileceğinin belirlendiği bölümdür. Yukarıdaki ekranda ki gibi değerleri 300 / 10 yaparsanız sisteme her 10 saniyede bir yeni kullanıcı girecekmiş gibi simüle edilir ve toplamda 300 kullanıcı ile test yapılır. Her bir kullanıcı belirlediğiniz min ve max wait değerlerine göre belirlediğiniz URL’ler arasında dolaşacaklardır.

Start butonuna bastığınız zaman load test başlayacak ve durumun izleneceği ve testin stop / start işlerinin yapılabileceği dashboard açılacaktır. Bir örneğini iki üstteki ekranda görebileceğiniz gibi burada anlık RPS (request per second), hangi URL’ye ne kadar request gönderildiği, response time değerleri ve fail eden herhangi bir istek olup olmadığı gibi istatistiki verilen görüntülenecektir.

Locust’un http://docs.locust.io/en/latest/ adresinde güzel bir dokumantasyonu bulunuyor. Yukarıda bahsettiğim basit test senaryosunun yanı sıra POST request’leri bir uygulamaya login olarak test yapma vs. gibi gelişmiş özellikleri de bulabilirsiniz.

Kaynak: https://www.syslogs.org