Jakiś czas temu poruszyliśmy w pracy ciekawą dyskusję. Rozmawialiśmy o wydajności. Niestety umowy i zobowiązania nie pozwalają mi ze szczegółami opowiedzieć czego dokładnie dotyczyła. Chcąc mniej więcej przybliżyć temat przyjmijmy że chcieliśmy porównać trzy scenariusze:
- Jeden request, który robi 1000 akcji
- 1000 request-ów, które robią 1 akcję
- 10 batch-y request-ów, które robią 100 akcji
O ile nie jestem wielkim fanem testów wydajnościowych (w wielu aplikacjach to tylko przerost formy nad treścią) to tym razem decyzja mogła nieść za sobą szereg konsekwencji. Podejmowanie decyzji na podstawie przeczucia to też nie moja bajka. Dlatego postanowiłem sprowadzić ten problem do postaci cyferek.
Świetnym narzędziem do szybkiego testowania endpoint-ów jest Apache Benchmark. Aby Tobie, a także sobie w przyszłości, ułatwić rozwiązywanie takich problemów przygotowałem listę gotowych do użycia skryptów.
Instalacja Apache Benchmark
Windows
Pierwszym krokiem w instalacji Apache Benchmark na Windows jest wejście na stronę https://www.apachelounge.com/download/ i ściągnięcie najnowszej paczki. Następnie należy skopiować dwa pliki ab.exe
i abs.exe
z katalogu bin
do katalogu, z którego będziesz chciał z nich korzystać. Oczywiście możesz także skopiować je do katalogu, który potem dodasz do zmiennej systemowej PATH
, aby skrócić lekko zapis komend.
Ubuntu
Aby zainstalować Apache Benchmark na Ubuntu wystarczą dwie komendy w terminalu
sudo apt-get update
sudo apt-get install apache2-utils
Mac OS X
Mac ma po prostu zainstalowany ten pakiet na starcie 😁
Skrypty
Podstawowy
ab -n 100 -c 10 https://onet.pl/
Zaczynamy od takiego Hello World
narzędzia apache benchmark. Jest to najbardziej podstawowe wywołanie. Spójrzmy na parametry:
-n
-> jest to całkowita liczba request-ów HTTP jaka zostanie wykonana-c
-> jest to liczba klientów, którzy zostaną utworzeni do wysyłania zapytań równoleglehttps://onet.pl/
-> adres, który chcemy przetestować. W tym przykładzie jest to strona onet.pl. Pamiętaj tylko, aby testować swoje strony, a nie próbować wykonać DDoS atak na małe serwery 😁 Jeszcze mała uwaga z mojej strony: pamiętaj, aby zawsze dodawać/
po domenie. Niestety Apache Benchmark nie uzna adresuhttps://onet.pl
jako poprawny.
Po krótkiej chwili, w konsoli, powinien ukazać się wynik. Dla naszego przykładu będzie wyglądać następująco:
$ ab -n 100 -c 10 https://onet.pl/
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking onet.pl (be patient).....done
Server Software: Ring
Server Hostname: onet.pl
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128
Server Temp Key: ECDH P-256 256 bits
TLS Server Name: onet.pl
Document Path: /
Document Length: 162 bytes
Concurrency Level: 10
Time taken for tests: 1.360 seconds
Complete requests: 100
Failed requests: 0
Non-2xx responses: 100
Total transferred: 42891 bytes
HTML transferred: 16200 bytes
Requests per second: 73.54 \[#/sec\] (mean)
Time per request: 135.982 \[ms\] (mean)
Time per request: 13.598 \[ms\] (mean, across all concurrent requests)
Transfer rate: 30.80 \[Kbytes/sec\] received
Connection Times (ms)
min mean\[+/-sd\] median max
Connect: 68 95 16.3 93 144
Processing: 15 24 6.7 23 60
Waiting: 15 22 5.4 22 50
Total: 91 119 16.8 116 182
Percentage of the requests served within a certain time (ms)
50% 116
66% 125
75% 130
80% 132
90% 140
95% 151
98% 171
99% 182
100% 182 (longest request)
Pokazało nam się wiele ważnych informacji, takich jak średnia długość request-ow HTTP, mediana czy odchylenie standardowe. Mamy również wstępną estymację ilości żądań, jaką jesteśmy w stanie obsłużyć w przeciągu sekundy.
Nagłówki i Uwierzytelnienie
ab -n 100 -c 10 -H "Content-Type: application/json" -v 4 https://swapi.dev/api/people/1/
Ustawienie nagłówka wymaga wykorzystania parametru -H , a następnie zapisania go zgodnie z nagłówkami HTTP. W niektórych przypadkach masz do dyspozycji parametry pomocnicze, które mogą znacząco skrócić zapis komendy. Np. zamiast -H "Content-Type: application/json"
możesz użyć:
ab -n 100 -c 10 -T application/json https://swapi.dev/api/people/1/
Tak samo w przypadku uwierzytelnienia metodą Basic, zamiast:
ab -n 100 -c 10 -H "Content-Type: application/json" -H "Authorization: Basic amVzbGlfdG9fY3p5dGFzejp0b196b3N0YXdfa29tZW50YXJ6XzpE" https://swapi.dev/api/people/1/
Możesz użyć parametru -A
ab -n 100 -c 10 -T application/json -A test:test https://swapi.dev/api/people/1/
Wysyłanie żądań POST i PUT
Aby wysłać żądanie POST lub PUT musisz w pierwszej kolejności przygotować plik, którego treść będzie wykorzystana jako ciało request-u HTTP.
Na potrzeby tego artykułu nazwijmy ten plik content.json
i niech posiada poniższą zawartość
{
"dummy": "data"
}
W momencie kiedy chcesz wykonać żądanie POST to musisz użyć flagi -p
ab -p content.json -T application/json -n 100 -c 10 -l https://myawesomeapi.com/
Natomiast w przypadku żądania PUT będzie to flaga -u
ab -u content.json -T application/json -n 100 -c 10 -l https://myawesomeapi.com/
W powyższych zapytaniach została dodana także flaga -l
, która informuje Apache Benchmark, że spodziewamy się zmiennej długości zwróconego dokumentu. Przydaje się to testowania stron z dynamicznym kontentem.
Zapisywanie wyników do pliku CSV
Za pomocą flagi -e
możemy zapisać wynik działania Apache Benchmark do pliku .csv
ab -e result.csv -n 10 -c 1 https://onet.pl/
Debugowanie i Logi
Ilość informacji, które dostajemy od Apache Benchmark jest dość spora. Niestety łatwo jest przeoczyć, kiedy zamiast odpowiedzi o statusie 2XX otrzymujemy 3XX lub 4XX. AB niestety traktuje wszystkie żądania nie zakończone statusem 500 jako poprawne. Dlatego warto chociaż raz uruchomić żądanie z flagą -v
, która pozwoli Ci na ustawienie poziomu logowania.
ab -e result.csv -n 10 -c 1 -v 4 https://onet.pl/
Jest kilka poziomów szczegółowości logów:
- 2 -> Wyświetli wszystkie warnings i logi o poziomie info
- 3 -> Wypiszę na konsoli kody odpowiedzi HTTP (404, 200, 202, etc.)
- 4 -> Wypisze także informację o nagłówkach
Podsumowanie
W dzisiejszym artykule pokazałem Ci jak rozpocząć swoją przygodę z testami wydajnościowymi. Pamiętaj jednak, że na wydajność ma wpływ wiele czynników. Nie mniej mam nadzieje, że artykuł okaże się pomocny i będzie to ułatwienie testowania wydajności Twoich endpoint-ów.
Do Następnego!