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ównolegle
  • https://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 adresu https://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!

PS. Spodobał Ci się ten artykuł?

Referencje