Nginx, ASP.NET Core i testiranje performansi – Apache Bench II deo

Ideja drugog dela je instalacija Nginx WEB servera, postavljanje jednostavne aplikacije i testiranje performansi u virtuelnom okruženju.

Priprema okruženja za testiranje

Kako smo pomenuli u prvom delu da je moguće koristiti Apache Bench i van Apache-a, ideja je da postavimo Nginx web server koji ćemo koristiti kao reverse proxy koji će preusmeravati zahteve ka našoj jednostavnoj web aplikaciji. sve to će raditi na Ubuntu 18.04 operativnom sistemu, a ista podešavanja važe i za Ubuntu 16.04. Celokupno okruženje biće postavljano kao virtuelna mašina kojoj će biti dodeljeno 2GB RAM-a i 2 procesorska jezgra.

Reverse proxy preuzima zahteve i prosleđuje ih odgovarajućim serverima. Oni koji šalju zahteve nisu svesni postojanja interne mreže.
Reverse proxy preuzima zahteve i prosleđuje ih odgovarajućim serverima. Oni koji šalju zahteve nisu svesni postojanja interne mreže.
Hardverske karakteristike servera
Hardverske karakteristike servera

Odgovor na pitanje zašto radimo na ovaj način umesto da direktno „gađamo“ web aplikaciju leži u performansama i skalabilnosti, tako da ovaj članak pokriva i određene DevOps veštine.

Nakon postavljanja okruženja, dobićemo situaciju nalik na sledećoj slici:

Šema okruženja
Šema okruženja

Instalacija Nginx web servera

Ubuntu 18.04 koristi apt paket menadžer. Prvo što je potrebno jeste osvežiti listu paketa naredbom update, a nakon toga izvršiti instalaciju Nginx-a.

$ sudo apt-get update
$ sudo apt-get install nginx

Nakon što se proces instalacije završi, potrebno je rekonfigurisati Firewall kako bi se omogućio pristup servisu. Nginx se sam tokom instalacije registruje na firewall, potrebno je samo reći ufw-u kako da radi sa Nginx-om. UFW (Uncomplicated FireWall) je podrazumevani firewall interfejs na Ubuntu distribucijama.

Sledeća komanda izlistava sve profile, gde možemo videti tri namenjena Nginx-u:

$ sudo ufw app list
output
Available applications:
  CUPS
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  • Nginx Full: Profil otvara oba porta – 80 za neenkriptovani web saobraćaj, i port 443 za TLS/SSL kriptovani saobraćaj.
  • Nginx HTTP: Otvara samo port 80.
  • Nginx HTTPS: Otvara samo port 443.

Sledeći korak jeste izabrati jedan od izlistanih profila. Pošto nemamo konfigurisan SSL na našem serveru, dovoljno je samo dozvoliti saobraćaj preko porta 80. To možemo uraditi na sledeći način:

$ sudo ufw allow 'Nginx HTTP'

Moguće je proveriti da li je izmena izvršena sledećom komandom:

$ sudo ufw status

Rezultat pomenute komande treba da sadrži linije Nginx HTTP i Nginx HTTP (v6).

Status: active

Output
To                         Action      From
--                         ------      ----          
Nginx HTTP                 ALLOW       Anywhere            
Nginx HTTP (v6)            ALLOW       Anywhere (v6)

Moguće je kao izlaz dobiti i Status: inactive. U tom slučaju, potrebno je uključiti ufw sledećom komandom:

$ sudo ufw enable

Nakon ovoga, server bi trebalo da bude aktivan. Kako bismo se uverili da server zaista radi, možemo pokrenuti i sledeću komandu:

$ systemctl status nginx

Očekivani izlaz komande je dat na slici ispod.

Nginx status
Nginx status

Sledeće što je poželjno uraditi jeste omogućavanje pristupa serveru preko operativnog sistema domaćina, odnosno preko operativnog sistema na kom je instalirana virtuelna mašina. Pošto je za rad korišćen Oracle VM VirtualBox, potrebno je izvršiti sledeću izmenu. Desni klik na VM -> Settings -> Network -> Adapter 1 -> Attached to -> Izabrati Bridged Adapter

Ovim je virtuelna mašina u potpunosti vidljiva u lokalnoj mreži.

Vidljivost računara u lokalnoj mreži.
Vidljivost računara u lokalnoj mreži.

NAPOMENA: Podešavanje izvršiti dok je virtuelna mašina isključena!

Sada je potrebno saznati ip adresu računara, to najlakše možemo uraditi komandom ifconfig za koju moramo instalirati alat net-tools sledećom komandom:

$ sudo apt-get install net-tools

Možemo izvršiti komandu ifconfig, a rezultat iste dat je na slici ispod.

$ ifconfig

Ukoliko je sve urađeno kako treba, u internet pretraživaču možemo uneti adresu http://192.168.0.18/ i nakon toga treba se učitati stranica kao na slici ispod.

Podrazumevana strana Nginx servera
Podrazumevana strana Nginx servera

ASP.NET Core

ASP.NET Core Logo
ASP.NET Core Logo

Obzirom da je moguće iskomplikovati strukturu web aplikacije na razne načine i time zakomplikovati testiranje, u ovom članku napravićemo jednostavnu web aplikaciju pomoću ASP.NET Core-a koji je sve popularniji, jer je otvorenog koda i podržan je na svim platformama (Windows, Linux, Mac).

Obzirom da nije akcenat na kreiranju same aplikacije, koristićemo onu koja dolazi kreiranjem ASP.NET Core WEB API projekta.

Instalacija .NET Core okruženja

Što se tiče instalacije, potrebno je ispratiti sledeću proceduru.

Prvo je potrebno registrovati Microsoft key i feed sledećim komandama:

$ sudo apt-get install python-pip
$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb

Nakon toga, vrši se instalacija .NET SDK – (Software Development Kit), seta biblioteka i alata koji omogućavaju developerima da kreiraju .NET Core aplikacije i biblioteke. Sastoji se od alata komandne linije.

$ sudo add-apt-repository universe
$ sudo apt-get install apt-transport-https
$ sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.2

Moguće je dobiti grešku vezanu za nemogućnost pronalaženja paketa dotnet-sdk-2.2 (nešto nalik: Unable to locate package dotnet-sdk-2.2). U tom slučaju potrebno je izvršiti sledeću komandu:

$ sudo dpkg --purge packages-microsoft-prod && sudo dpkg -i packages-microsoft-prod.deb

Ukoliko ni ova komanda ne reši problem, moguće je manuelno izvršiti instalaciju na sledeći način:

$ sudo apt-get install -y gpg
$ wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
$ sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/prod.list
$ sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
$ sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
$ sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
$ sudo apt-get install -y apt-transport-https
$ sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.2

Kreiranje web API aplikacije

Nakon instalacije, napravićemo folder u koji ćemo smestiti web aplikaciju (nije bitna lokacija jer ćemo preko Nginx-a preusmeravati saobraćaj na nju) i u njemu napraviti novi webapi projekat.

$ dotnet new webapi -o testapi

Kao rezultat očekujemo izlaz koji sadrži nešto nalik sledećoj poruci:

...
Getting ready...
The template "ASP.NET Core Web API" was created successfully.
 
Processing post-creation actions...
Running 'dotnet restore' on testapi/testapi.csproj...
  Restoring packages for /home/node-01/Desktop/demoWebApi/testapi/testapi.csproj...
  Generating MSBuild file /home/node-01/Desktop/demoWebApi/testapi/obj/testapi.csproj.nuget.g.props.
  Generating MSBuild file /home/node-01/Desktop/demoWebApi/testapi/obj/testapi.csproj.nuget.g.targets.
  Restore completed in 15.89 sec for /home/node-01/Desktop/demoWebApi/testapi/testapi.csproj.
 
Restore succeeded.

Nakon ovog koraka, napravili smo najjednostavniju ASP.NET Core Web API aplikaciju.

Pokretanje aplikacije vršimo komandom (podrazumevamo da smo u folderu testapi):

$ dotnet run

Nakon ovog dela, preostaje nam da objavimo aplikaciju i kreiramo servis, kako bi se aplikacija neprestano izvršavala. Poslednji korak biće povezivanje Nginx-a i same aplikacije. Tek nakon toga možemo se posvetiti testiranju web aplikacije.

Postavljanje aplikacije

Objavljivanje aplikacije

Iz foldera web aplikacije (testapi) potrebno je izvršiti sledeće komande:

$ dotnet publish --configuration Release
$ cd ..
$ mv testapi/bin/Release/ /var/www

Sada kada bismo u folderu /var/www izvršili komandu $dotnet testapi.dll, rezultat bi bila pokrenuta aplikacija.

$ dotnet testapi.dll

Otvaranje portova

Pošto aplikacija sluša na portovima 5000 i 5001, moramo ih privremeno otvoriti komandom:

$ sudo ufw allow 5000/tcp
$ sudo ufw allow 5001/tcp

Kada se konfiguriše Nginx, prestaje potreba za ovim portovima pa iste možemo zatvoriti komandama:

$ sudo ufw deny 5000/tcp
$ sudo ufw deny 5001/tcp

Kreiranje servisa

Kako bismo omogućili pokretanje web aplikacije prilikom startovanja servera i automatsko restartovanje ukoliko dođe do nekog problema, neophodno je kreirati servis na sledeći način.

Napravićemo testapi servis u Systemd, kome ćemo reći gde se nalazi naša aplikacija i kako treba da se pokrene. Takođe dodaćemo još neka podešavanja vezana za restartovanje i samo okruženje.

$ sudo nano /etc/systemd/system/testapi.service
[Unit]
Description=Demo ASP.Net Project
 
[Service]
WorkingDirectory=/var/www/testapi
ExecStart=/usr/bin/dotnet /var/www/Release/netcoreapp2.2/testapi.dll
Restart=always
RestartSec=10
SyslogIdentifier=DemoProject
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
 
[Install]
WantedBy=multi-user.target

Konfiguracija nginx-a

Poželjno je prvo napraviti rezervnu kopiju fajla nad kojim ćemo vršiti izmene sledećom komandom:

$ cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default-backup 

Nakon toga, isti možemo menjati. Neophodno je zameniti server blok sledećim blokom:

server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         https://192.168.0.18:5001;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

Sada možemo proveriti i potvrditi izmene komandama:

$ sudo nginx -t
$ sudo nginx -s reload

Ukoliko smo sve uradili kako treba, sa bilo kog računara lokalne mreže možemo pristupiti kreiranoj ASP.NET Core aplikaciji unosom sledeće adrese:

http://192.168.0.18/api/values
Prikaz odgovora servera na računaru u lokalnoj mreži.
Prikaz odgovora servera na računaru u lokalnoj mreži.

Testiranje

Poređenje sa testom iz dela I

Zajedno sa virtuelnom mašinom na kojoj hostujemo aplikaciju, pokrećemo i virtuelnu mašinu na kojoj se nalazi Apache Bench.

Možemo pokrenuti isti test kao za sajt Instituta za Matematiku i Informatiku i uporediti rezultate:

$ ab -n 100 -c 10  http://192.168.0.18/api/values

Dobićemo sledeći izlaz:

Output:
node-bench@node-bench:~$ ab -n 100 -c 10 http://192.168.0.18/api/values
This is ApacheBench, Version 2.3 
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
 
Benchmarking 192.168.0.18 (be patient).....done
 
 
Server Software:        nginx/1.14.0
Server Hostname:        192.168.0.18
Server Port:            80
 
Document Path:          /api/values
Document Length:        28 bytes
 
Concurrency Level:      10
Time taken for tests:   0.495 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      22500 bytes
HTML transferred:       2800 bytes
Requests per second:    201.86 [#/sec] (mean)
Time per request:       49.539 [ms] (mean)
Time per request:       4.954 [ms] (mean, across all concurrent requests)
Transfer rate:          44.35 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       1
Processing:    19   48  13.5     48      90
Waiting:       18   48  13.5     47      90
Total:         19   49  13.5     48      91
 
Percentage of the requests served within a certain time (ms)
  50%     48
  66%     52
  75%     54
  80%     56
  90%     66
  95%     79
  98%     83
  99%     91
 100%     91 (longest request)

Možemo primetiti značajno bolje performanse u odnosu na prvo testiranje. Razlog je taj što ovde vraćamo samo dva niza karaktera (value1, value2, value3) koji su drastično manji u odnosu na sadržaj koji se vraća na testu Instituta za Matematiku i Informatiku, tako da i to treba imati u vidu prilikom testiranja.

Testiranje više URL-ova istovremeno

Pored testiranja svake rute pojedinačno, moguće je izvršiti i test u kome ćemo „gađati“ obe rute. Potrebno je napisati shell skriptu koja će sadržati sve testove.

Prvo ćemo otvoriti nano editor za fajl testScript.sh:

$ nano testScript.sh

U fajl je potrebno uneti sve testove koje želimo da izvršimo. Kako naša aplikacija ima samo dve testne rute: /api/values, /api/values/{broj}, u fajl ćemo upisati samo njih.

ab -n 100 -c 10 http://192.168.0.18/api/values > test1.txt
ab -n 100 -c 10 http://192.168.0.18/api/values/6 > test2.txt

NAPOMENA: Deo komande „> testX.txt “ preusmerava izlaz u odgovarajuće fajlove, kako bismo lakše pročitali i uporedili rezultate.

Sledeći korak jeste učiniti fajl izvršnim, sledećom komandom:

$ chmod u+x testScript.sh

Nakon toga, preostaje nam samo da pokrenemo fajl na sledeći način:

$ ./testScript.sh

Za očekivati je da rezultat prvog testa bude bolji od rezultata drugog testa, što se da videti.

Output 1:
...
Time taken for tests:   0.483 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      22500 bytes
HTML transferred:       2800 bytes
Requests per second:    207.11 [#/sec] (mean)
Time per request:       48.282 [ms] (mean)
Time per request:       4.828 [ms] (mean, across all concurrent requests)
Transfer rate:          45.51 [Kbytes/sec] received
...
Output 2:
...
Time taken for tests:   0.490 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      19600 bytes
HTML transferred:       500 bytes
Requests per second:    203.91 [#/sec] (mean)
Time per request:       49.041 [ms] (mean)
Time per request:       4.904 [ms] (mean, across all concurrent requests)
Transfer rate:          39.03 [Kbytes/sec] received
...

Razlika u Total transferred i HTML transfered ogleda se u tome da prvi odgovor servera vraća niz od tri stringa (value1, value2, value3), dok drugi vraća samo jedan string (value), ukoliko se poveća broj zahteva serveru, performanse će drastičnije opasti.

Flagovi

Test možemo proširiti upotrebom nekih od sledećih flagova kojima možemo prilagoditi samo testiranje našim potrebama.

Verbose -v

Odličan flag za debug prilikom testiranja svakog zahteva koji se šalje serveru. Ukoliko se test završi neočekivano brzo, to može biti signal da je došlo do nekog problema. Pomoću ovog flaga moguće je videti šta je rezultat testiranih ruta. Unećemo -v 2 kako bismo pratili uspeh svakog zahteva serveru. U terminalu ćemo dobiti izlaz header-a i body dela odgovora.

Izgled komande za testiranje

$ ab -n 100 -v 2 http://192.168.0.18/api/values

Output sa greškom (promenjen url servera u nginx konfiguracionom fajlu)

WARNING: Response code not 2xx (502)
LOG: header received:
HTTP/1.1 502 Bad Gateway
Server: nginx/1.14.0 (Ubuntu)
Date: Wed, 13 Mar 2019 13:32:51 GMT
Content-Type: text/html
Content-Length: 182
Connection: close
 
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.14.0 (Ubuntu)</center>
</body>
</html>

Vidimo da je dobijen status 200, takođe vidimo i šta api ruta treba da vrati ([„value1″,“value2″,“value3“])

---
GET /api/values HTTP/1.0
Host: 192.168.0.18
User-Agent: ApacheBench/2.3
Accept: */*
 
 
---
LOG: header received:
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Wed, 13 Mar 2019 13:37:21 GMT
Content-Type: application/json; charset=utf-8
Connection: close
 
["value1","value2","value3"]

Keep-alive -k

Kada klijent šalje HTTP zahtev, kreira se konekcija ka serveru, server šalje odgovor i nakon toga se konekcija zatvara. Ciklus se ponavlja za svaki zahtev. Međutim, sa keep-alive flagom, konekcija se ne prekida i dobija se takozvana perzistentna konekcija. Na ovaj način očekujemo da server bude u mogućnosti da obradi mnogo više zahteva, jer ne gubi vreme na kreiranje i zatvaranje konekcije.

Promenljiva veličina dokumenta -l

Ukoliko je stranica promenljive dužine, to treba uzeti u obzir, jer će se prilikom testiranja javiti greška ukoliko dođe do promene dužine. Ovim flagom bismo rešili problem testa iz prvog dela, gde je skoro 50% stranica testirano sa greškom zbog promene dužine dokumenta.

Timelimit -t

Jedan od specifičnih flagova jeste timelimit. Njime ograničavamo vreme trajanja testa. Podrazumevano nema ograničenja. Ukoliko se postavi vrednost, test će se prekinuti nakon isteka intervala, nezavisno od toga da li je poslao sve zahteve ili ne. Pošto test ne može da se završi ranije, Apache Bench će nastaviti da šalje zahteve serveru sve dok ne istekne vreme.

$ ab -n 100 -c 10 -t 60   http://192.168.0.18/api/values
Benchmarking 192.168.0.18 (be patient)
...
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requests
...

Flag -r

Moguće je omogućiti da se test izvrši do kraja, čak i ako se javi greška vezana za socket error. Ovim flagom test će se izvršiti do kraja, a sve greške biće prijavljene.

Flag -H

Apache Bench nam daje mogućnost da specificiramo kako će izgledati zaglavlje pomoću flaga -H. Tako npr. možemo uvesti -H „Accept-Encoding: gzip, deflate“ header i omogućiti da server brže obrađuje zahteve.

Flag -C

Odnosi se na pisanje testova kod zahteva koji koriste Cookie (kolačiće). Dovoljno je samo navesti -C session_name = 192.168.0.18-643dad04-3c34 za testiranje.

Poređenje testova

Početni test

Izmenićemo fajl testScript.sh koji smo već koristili. Sada ćemo slati 10000 zahteva, tako da će se 100 izvršavati istovremeno. Izlaze ćemo pamtiti u odgovarajućim tekstualnim fajlovima.

ab -n 10000 -c 100 http://192.168.0.18/api/values > test1.txt

Rezultat testa dat je ispod. Kao što se da primetiti, server i dalje uspeva bez ikakvih problema da obradi sve zahteve.

Test je trajao 4.132 sekunde umesto 0.495 sekundi koliko je trajao sa 100 zahteva od kojih je 10 bilo konkurentno.

...
Concurrency Level:      100
Time taken for tests:   4.768 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1810000 bytes
HTML transferred:       280000 bytes
Requests per second:    2097.26 [#/sec] (mean)
Time per request:       47.681 [ms] (mean)
Time per request:       0.477 [ms] (mean, across all concurrent requests)
Transfer rate:          370.71 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    3   3.1      2      23
Processing:     8   44  14.2     43     114
Waiting:        7   43  13.9     42     112
Total:          8   47  14.2     46     118
 
Percentage of the requests served within a certain time (ms)
  50%     46
  66%     52
  75%     55
  80%     57
  90%     65
  95%     73
  98%     82
  99%     88
 100%    118 (longest request)

Test sa gzipped keep-alive flagovima

$ ab -n 10000 -c 100 -k -H "Accept-Encoding: gzip, deflate"  http://192.168.0.1/

Dobijeni izlaz pokazuje bolji transfer rate. Tako sada imamo 2349.01 zahteva u seknudi umesto pređašnjih 2097.26 zahteva u sekundi. Vreme po zahtevu palo je sa 47.681 ms na 42.571 ms.

...
Concurrency Level:      100
Time taken for tests:   4.257 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1810000 bytes
HTML transferred:       280000 bytes
Requests per second:    2349.01 [#/sec] (mean)
Time per request:       42.571 [ms] (mean)
Time per request:       0.426 [ms] (mean, across all concurrent requests)
Transfer rate:          415.21 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    3   3.1      2      18
Processing:     8   39  10.8     38      84
Waiting:        7   38  10.7     37      83
Total:          8   42  10.3     41      87
 
Percentage of the requests served within a certain time (ms)
  50%     41
  66%     45
  75%     48
  80%     50
  90%     56
  95%     61
  98%     68
  99%     72
 100%     87 (longest request)

Granica servera i šta dalje

Moguće je doći u situaciju kada serveru treba puno vremena kako bi vratio odgovor ili kada test rezultuje greškom usled nemogućnosti servera da obradi sve zahteve. U tim situacijama postoje dva rešenja, horizontalna ili vertikalna nadogradnja.

Što se tiče vertikalne nadogradnje, ona se zasniva na tome da se nadograde komponente servera, što je jednostavniji pristup, ali nije moguće beskonačno dugo na ovaj način rešavati problem. Bolje rešenje leži u horizontalnom skaliranju, gde bi se postavio još jedan identičan server koji bi opsluživao korisnike onda kada prvi server nije u mogućnosti ili jednostavno postaviti pravila kada se zahtevi obrađuju preko jednog, a kada preko drugog servera.

U ovom članku pogledaćemo primer u kome serveru treba više od 3 sekunde da obradi zahteve klijenta, dok u narednom delu videćemo kako je moguće rešiti problem horizontalnog skaliranja.

Komanda za testiranje:

$ ab -n 30000 -c 250 http://192.168.0.18/api/values
Concurrency Level:      250
Time taken for tests:   121.060 seconds
Complete requests:      300000
Failed requests:        0
Total transferred:      54300000 bytes
HTML transferred:       8400000 bytes
Requests per second:    2478.11 [#/sec] (mean)
Time per request:       100.883 [ms] (mean)
Time per request:       0.404 [ms] (mean, across all concurrent requests)
Transfer rate:          438.02 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    8  64.1      2    1048
Processing:     6   92 176.2     61    3326
Waiting:        2   90 176.2     60    3319
Total:          8  100 187.8     66    3328
 
Percentage of the requests served within a certain time (ms)
  50%     66
  66%     74
  75%     81
  80%     85
  90%     99
  95%    120
  98%   1081
  99%   1104
 100%   3328 (longest request)

Za demonstraciju je uzet server sa solidnim performansama (dva jezgra i 2GB RAM-a), a situacija postaje dramatična ukoliko bismo koristili server sa jednim jezgrom i 1GB RAM-a. U toj situaciji za isti test primer dolazimo u situaciju da se najduži zahtevi obrađuju skoro 16 sekundi!

Isti test nad serverom sa jednim procesorskim jezgrom i 1GB radne memorije.

Concurrency Level:      250
Time taken for tests:   264.643 seconds
Complete requests:      300000
Failed requests:        0
Total transferred:      54300000 bytes
HTML transferred:       8400000 bytes
Requests per second:    1133.60 [#/sec] (mean)
Time per request:       220.536 [ms] (mean)
Time per request:       0.882 [ms] (mean, across all concurrent requests)
Transfer rate:          200.37 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   96 427.4      0   15489
Processing:    16  124  87.4    107    3277
Waiting:       16  124  87.4    107    3277
Total:         23  220 447.0    109   15695
 
Percentage of the requests served within a certain time (ms)
  50%    109
  66%    125
  75%    142
  80%    153
  90%    205
  95%   1127
  98%   1215
  99%   1456
 100%  15695 (longest request)

Tumačenje rezultata testova

Grafikoni poređenja performansi

Na slikama ispod moguće je videti poređenja i objašnjenja grafikona. Ideja je uporediti testove gde se serveri normalno ponašaju sa primerom gde je server preopterećen.

Dakle, razne parametre treba uzeti u obzir kada je reč o rezultatima Apache Bench-a. Mereni rezultati služe kao značajna pomoć prilikom dizajniranja sistema na kom će se postaviti aplikacija i korisni su za otkrivanje potencijalnih uskih grla na vreme. Prikazan je primer koji demonstrira koliko je bitna činjenica na kakvom serveru se nalazi aplikacija, koliko ima procesora, RAM-a, memorije itd.

Zaključak

U ovom članku prošli smo ceo proces od postavljanja aplikacije, preko upotrebe nginx reverse proxy-ja, do testiranja aplikacije. Ovi koraci su važni svakome ko pokuša sam da kreira efikasan sistem i postavi aplikaciju. Takođe, pokazali smo koliko je bitan hardver i testiranje performansi pre puštanja aplikacije u produkciju i u toku prosukcionog života aplikacije. U sledećem delu biće više reči o horizontalnom skaliranju web aplikacija.

Korisni linkovi

Autor: Bojan Piskulić

Svestrana osoba koja voli tehnologiju, trenutno se pretežno bavim web-om, u slobodno vreme trudim se da naučim što više novih stvari.

Bojan Piskulić

Svestrana osoba koja voli tehnologiju, trenutno se pretežno bavim web-om, u slobodno vreme trudim se da naučim što više novih stvari.