Testowanie obciążenia. Porównanie narzędzi k6 i JMeter

Testowanie obciążenia. Porównanie narzędzi k6 i JMeter
Przyjrzymy się dziś dwóm narzędziom służącym do testowania obciążenia. Nie wskażemy Wam, które z nich jest w naszej ocenie lepsze, ale spróbujemy przybliżyć, w jakich sytuacjach sprawdzą się one lepiej.

Darmowym narzędziem typu open source, służącym do testowania obciążenia, w całości zbudowanym w Javie, jest JMeter. Pierwszy raz wydany w 1998 roku, z miejsca podbił serca użytkowników, oddając w ich ręce coś, za co do tej pory inne firmy kazały sobie słono płacić. Chociaż w JMeter skrypty można rozszerzać za pomocą kodu, większość z nich budowana jest za pomocą interfejsu użytkownika. Z kolei w 2017 roku LoadImpact wydał swoje narzędzie typu open source przeznaczone do testowania obciążenia – k6. Narzędzie stworzone jest w oparciu o Go, jednak skrypty bazują na JavaScript. Główną cechą k6 są skrypty wymagające kodowania co promuję doświadczonych programistów. 

Nie ma jednoznacznie "najlepszego" narzędzia; istnieje tylko właściwe narzędzie, dobrane odpowiednio do projektu i jego kontekstu. Postaramy się jednak udzielić odpowiedzi na pytanie w jakich sytuacjach sprawdza się każde z tych narzędzi?

Co wyróżnia JMeter?

  1. GUI.

    Użycie Graficznego Interfejsu Użytkownika przyda się w sytuacjach, w których zespół nie ma doświadczenia w wykonywaniu testów obciążeniowych i musi nauczyć się od podstaw nowego narzędzia. To, które oparte jest na GUI, może okazać się najmniej problematycznym wyborem dla testerów, którzy są przyzwyczajeni do bezkodowych interfejsów użytkownika (takich jak Postman lub SoapUI).
  2. Obsługa wielu protokołów i funkcji.

    Lista protokołów obsługiwanych przez JMeter jest długa. Ma on także większość funkcji potrzebnych do wykonania podstawowych testów obciążenia, co znaczy, że nie trzeba samemu go okodować. Struktura elementów nadrzędnych i podrzędnych oznacza, że pojawia się możliwość modyfikacji określonych elementów, takich jak modyfikacja wszystkich żądań http.
  3. Doświadczona społeczność z mnóstwem dokumentacji.

    Początki JMetera sięgają 1998 roku. Jest on obecny na prawie każdym fachowym forum społecznościowym i bez względu na to, jak konkretny będzie przypadek użycia tego narzędzia , to są szanse, że ktoś już kiedyś zrobił to samo. JMeter może pochwalić się obszerną i bardzo dokładną dokumentacją swoich komponentów, w której każdy element, funkcja i jego właściwość są omówione niezwykle szczegółowo. Oprócz oficjalnej dokumentacji istnieją także setki książek, samouczków i kursów stworzonych przez jego pasjonatów. Dowodem na to jest repozytorium JMeter na GitHubie, które pod koniec 2020 roku miało już ponad 17000 zatwierdzeń. 
  4. Tanie rozwiązanie do testowania obciążenia rozproszonego.

    JMeter sprawdzi się doskonale, gdy niezbędny jest tani sposób na testowanie obciążenia rozproszonego. Zapewnia on framework do uruchomienia takiego typu testów. Oznacza to zwiększenie generowanego obciążenia za pomocą zwiększenia liczby użytkowników wirtualnych i uruchomienie wielu równoległych skryptu w różnych generatorach obciążenia. W JMeter dzieje się to poprzez wyznaczenie węzła (controller node) i umożliwienie skonfigurowania tzw. węzłów roboczych (workers nodes), z których każdy posiada kopię jmeter-server, narzędzia dołączonego do każdej instalacji JMeter (w jmeter/bin).

    testowanie-obciazenia-k6-jmeter-1.jpg
    *) źródło: Apache JMeter

    Węzły robocze w kolejnym kroku uruchamiają kopie planu testów i obciążają serwer aplikacji. Jako węzły robocze można użyć maszyny lokalne, można wykorzystać do tego również chmurę. Takie rozproszone wykonanie zajmuje co prawda trochę czasu, ale działa satysfakcjonująco dobrze.

    k6 z kolei obsługuje tryb testowania obciążenia rozproszonego za pośrednictwem Kubernetes, który umożliwia utworzenie niestandardowego obiektu zasobu k6 w klastrze Kubernetes. 

    W porównaniu do k6 JMeter okazuje się dość zasobożerny i dlatego jest bardziej prawdopodobne, że będzie wymagał więcej generatorów obciążenia. W zależności od zasobów pojedynczego generatora JMeter może obsługiwać średnio około tysiąca użytkowników wirtualnych, a skalowanie testu poza ten punkt będzie wymagało konfiguracji uruchomienia rozproszonego. 
  5. Gotowe raporty wbudowane w narzędziu do testowania obciążenia.

    JMeter pozwala decydować, w jakim formacie powinny być wyświetlane wyniki. Debugowanie? Można użyć drzewa wyników. Potrzebne są metryki do testu obciążenia? Do wyboru jest także raport podsumowujący lub zbiorczy. 

    testowanie-obciazenia-k6-jmeter-2.jpg
    Ponadto JMeter pozwala generować raporty w HTML tworzone na podstawie wyników uruchomienia testów obciążenia. Są one dość ograniczone, ale też dość funkcjonalne. Mają też kilka domyślnych wykresów, które ułatwiają przeanalizowanie wyników testów obciążenia. Nie są interaktywne, ale łatwe do wygenerowania i stanowią dobry punkt wyjścia do stworzenia szablonu raportu z testów

    testowanie-obciazenia-k6-jmeter-3.jpg
    W przeciwieństwie do JMeter k6 nie może pochwalić się wbudowanym raportowaniem. Można za to zintegrować go z wieloma innymi narzędziami do analizy danych, np. Grafana, Datadog, New Relic, Amazon CloudWatch i k6 Cloud, które ostatecznie są lepszymi narzędziami analitycznymi i mogą dostarczyć więcej informacji niż te, które dają raporty generowane przez JMeter, ale wymagają skonfigurowania innego narzędzia do analizy testów, a to jak wiadomo, wymaga dodatkowego nakładu czasu i pracy. 

Co wyróżnia k6?

  1. Szybki start.

    Samo rozpoczęcie pracy z obydwoma narzędziami jest szybkie i proste, ale dzieje się tak z różnych powodów. Proces instalacji k6 jest szybki, co więcej nie wymaga on nodeJS ani żadnych innych komponentów. JMeter też instaluje się łatwo, jednak zanim przejdziemy do jego zainstalowania, musimy mieć zainstalowaną Javę. Tu mogą pojawić się problemy z dodawaniem zmiennych środowiskowych potrzebnych do jej działania, czasami trudno też określić, która wersja Javy jest właściwa. 

    k6 obsługuje wtyczki, ale nie są one potrzebne. W większości przypadków wbudowana funkcjonalność narzędzia powinna w zupełności wystarczyć (oprócz wspomnianych wcześniej raportów). Kontrastuje to z JMeter, gdzie wszystko jest wtyczką, łącznie z samym menedżerem wtyczek. Określa się, że istnieje standardowy zestaw wtyczek, które należy pobrać, zanim rozpocznie się korzystanie z narzędzia, a to może wprowadzać zamieszanie, zwłaszcza wśród nowych użytkowników narzędzia. 

    Skrypty k6 stworzone są w JavaScript, co znacznie ułatwia ich pisanie i uruchamianie. Wszystko czego użytkownik potrzebuje, to jeden instalator lub pojedyncze polecenie na terminalu oraz dowolny edytor tekstu. W przypadku JMeter, przed rozpoczęciem konieczne jest zainstalowanie kilku rzeczy lokalnie: Java, samego JMeter-a i standardowy zestaw wtyczek, których użytkownik będzie potrzebować do pracy z narzędziem.
  2. Maksymalizacja wydajność i efektywność.

    Kiedy mowa jest o symulacji wielu wirtualnych użytkowników, musimy przekalkulować niską wydajnością narzędzia, która równa jest wysokim kosztom uruchomienia testów. Liczba używanych generatorów obciążenia będzie wiązać się z kosztem, niezależnie od tego, czy jest to koszt ich nabycia i utrzymania (lokalnie), czy koszt usługi w chmurze. Z tego też względu sensowne będzie rozważenie ograniczeń wydajności narzędzia do testowania obciążenia przed użyciem go do kontroli wydajności własnej aplikacji.

    k6 napisany jest w Go, który zbudowany jest właśnie z myślą o wydajności. To język kompilowany, który nie wymaga interpretacji, jak to się dzieje w przypadku Javy czy Pythona, nie jest on szczególnie złożony, ani nie posiada zewnętrznych zależności. Im mniej ruchomych części w całym mechanizmie, tym mniej potencjalnych źródeł wąskiego gardła. Najprostszym i najczęstszym sposobem, w jaki narzędzie do testowania obciążenia może uruchomić użytkownika wirtualnego, jest przypisanie jednego użytkownika wirtualnego do jednego jądra lub wątku systemu operacyjnego. Jednak w paradygmacie 1 wątek = 1 użytkownik wirtualny pojawia się poważna wada: kiedy wirtualny użytkownik czeka na odpowiedź lub wykonuje zaprogramowaną funkcję sleep(), wątek jest blokowany i nie może w nim przetwarzać innych zadań. 

    W k6 każdy wirtualny użytkownik jest uruchamiany na tzw. goroutine, a nie na wątku. Goroutine sterowane są za pomocą czegoś, co nazywa się Go Scheduler, działający jak policjant sterujący ruchem; potrafi on ponownie wykorzystać nieaktywne wątki i inteligentnie przypisuje prace, umożliwiając przekazywanie jej między wątkami. Jest to ta sama zasada, na której opierają się load balancery: zewnętrzny monitor nadzorujący przepływ pracy poprawia ogólną wydajność. Możliwość wykorzystania wbudowanych optymalizacji wydajności języka Go przekłada się na mniejsze wykorzystanie pamięci, dzięki temu jeden wątek z k6 nie przekracza 100 kb, podczas gdy wątek JVM, taki jak JMeter, używa domyślnego 1 MB. Co prawda Java pozwala użytkownikowi dostosować wykorzystanie pamięci przez aplikację, dlatego też różnica zazwyczaj nie będzie aż tak wyraźna, ale nadal warto zauważyć, że Go ma znacznie niższy punkt wyjścia.
  3. Gwarancja większej wydajności

    Lepsza wydajność k6 oznacza, że do wygenerowania określonej wielkości obciążenia potrzeba mniej generatorów. Dodatkowo k6 ma niższe zużycie pamięci, dzięki czemu może on obsługiwać więcej wirtualnych użytkowników i generować większe niż przeciętnie obciążenie. Niezależnie od tego, czy używane są lokalne generatory obciążenia, czy w chmurze, finalny koszt aprowizacji będzie z pewnością mniejszy. Jest to oszczędność, która może zadecydować o wyborze k6 przez zespoły dbające o swój budżet.

    k6 różni się też od wielu innych narzędzi do testowania obciążenia tym, w jaki sposób obsługuje zasoby sprzętowe. Pojedynczy proces k6 efektywnie wykorzystuje wszystkie rdzenie procesora na maszynie generującej obciążenie. Pojedyncza instancja k6 często wystarcza do wygenerowania obciążenia 30 000-40 000 jednoczesnych użytkowników (VU), co w efekcie generuje do 300 000 żądań na sekundę (RPS).

    Kolejnym elementem pozytywnie wpływającym na wydajność k6 jest brak GUI, które zazwyczaj znacznie obciążają aplikację. Kiedy przeprowadzany jest test obciążenia, najbardziej wskazane jest uruchomienie go z wiersza poleceń. Narzędzia do testowania obciążenia oparte na kodzie działają od samego początku. Wyeliminowanie GUI oznacza wyeliminowanie jednego z problemów. 
  4. Przeprowadzanie testów zorientowanych na cel.

    Rozpoczynając nowy projekt testowania obciążenia należy zadać sobie istotne pytanie: „dlaczego”? Plany testów powinny być tworzone w odpowiedzi na powody, dla których zespół chce przeprowadzić testy obciążeniowe, co powinno znaleźć odzwierciedlenie w wymaganiach niefunkcjonalnych. Z kolei wymagania niefunkcjonalne powinny dawać pewne wskazówki dotyczące granic wydajności. JMeter standardowo nie obsługuje progów na poziomie testu. Można to oczywiście obejść na kilka sposobów, jednak nadal są to tylko obejścia, które nie są dostarczane razem z JMeter lub nie odnoszą się odpowiednio do tworzenia różnych typów progów (błąd, czas odpowiedzi, przepustowość, procesor, pamięć). Najczęściej stosowanym przez użytkowników rozwiązaniem jest eksportowanie surowych danych z JMeter i samodzielne przeprowadzanie analizy za pomocą innego narzędzia.
  5. Wykorzystywanie w zespole, w którym skrypty może pisać więcej niż jedna osoba.

    k6 sprawdzi się jako narzędzie, z którym oprócz testerów mogą pracować także programiści. Wypełnia ono lukę, wprowadzając koncepcję i funkcje testerskie do środowiska i językiem, z którym programiści już się zetknęli. JavaScript jest łatwym podejściem do pisania skryptów testów obciążenia, a k6 działa dobrze z dowolnym IDE lub edytorem tekstu. 
  6. Łatwość w utrzymaniu

    Jedynym zmartwieniem dotyczącym k6 to jego wersje oraz wersja skryptów. Żadne inne zależności nie są wymagane. Niezbędne będzie jedynie śledzenie wtyczek, jeśli oczywiście są one wykorzystywane do pracy z narzędziem. To zupełne przeciwieństwo JMeter, przy pracy z którym należy pamiętać o aktualizacji wielu elementów, takich jak wersja samego JMetera, Javy, wersje wtyczek, a także samego skryptu. Kolejnym ułatwieniem jest łączenie kodu testowego z kodem aplikacji. Jeśli kod aplikacji napisany jest w JavaScript, k6 będzie właściwym narzędziem do testowania obciążenia. Pozwala to tworzyć testy, które są ściśle zintegrowane z kodem aplikacji, importując obiekty i bezpośrednio z nimi współpracując. Takie podejście ograniczy dużo czasu spędzanego na refaktoryzacji skryptów testowych, gdy obiekty są zmieniane.
Funkcja JMeter k6
Język Java Go
Język skryptu Java (Groovy, Beanshell itp.) JavaScript
Protokoły Obsługuje większość protokołów za pośrednictwem wtyczek (HTTP/1.1, SOAP, FTP, JDBC, LDAP, MOM via JMS, SMTP, POP3, IMAP, shell scripts, TCP, Java objects) Natywnie obsługuje mniej nowoczesnych protokołów (HTTP/1.1, HTTP/2, WebSockets, gRPC)
Automatyzacja przeglądarki Tak, przy użyciu Selenium/WebDriver Tak, przy użyciu przeglądarki xk6
Zależności zewnętrzne Java żadne
Wykorzystanie zasobów Słaby - jeden generator obciążenia może symulować kilka tysięcy wirtualnych użytkowników Bardzo dobry - jeden generator obciążenia może symulować dziesiątki tysięcy wirtualnych użytkowników
Zarządzanie pamięcią Musi być ustawiona pamięć sterty JVM Standardowo wykorzystuje pamięć generatora obciążenia
Model wątkowości 1 wątek: 1 użytkownik wirtualny; Niższa wydajność, wyższy koszt zasobów 1 Goroutine: 1 Użytkownik wirtualny; Większa wydajność, niższe koszty zasobów
Łatwość pisania skryptów Oparte na GUI, z blokami kodu oparty na kodzie; Wtyczka VSCode
Progi poziomów obciążenia Nie, tylko indywidualne zapytania Tak
Format skryptu XML JavaScript
Współpraca Trudne do jednoczesnej pracy; narzędzie przyjazne testerowi, niezbędna aplikacja GUI do edycji Przyjazny dla programistów, łatwy w wersjonowaniu, format Javascript sprzyja współpracy
Utrzymanie Skrypty szczegółowe; Format XML jest trudny do odczytania Bardziej zwięzłe skrypty; JavaScript jest łatwy do odczytania
Społeczność Od 1998; Wiele samouczków innych firm; Obszerna dokumentacja; Brak oficjalnej społeczności Od 2017 roku; Obszerna dokumentacja; Mniej samouczków innych firm; Oficjalna społeczność
Wsparcie wtyczek Dostęp do bogatej bazy wtyczek, które są wymagane dla wielu funkcji Większość funkcji jest obsługiwana w standardzie, ale obsługa wtyczek jest nowością, a ich dostępność niewielka

Podsumowanie

Jedno i drugie narzędzie radzi sobie dobrze w generowaniu obciążenia. Niestety ani JMeter, ani k6 nie obsługują szczegółowej analizy wyników. 

JMeter jest więc najlepszy dla:

  • tradycyjnych zespołów testowych,
  • użytkowników, którzy szukają narzędzia do testowania opartego na GUI z mnóstwem samouczków i szeroką obsługą protokołów,
  • dotychczasowych użytkowników narzędzi komercyjnych, takich jak LoadRunner i NeoLoad.

k6 jest z kolei najlepszy dla:

  • współpracujących ze sobą zespołów inżynierskich, w których testowanie obejmuje wiele ról,
  • użytkowników, którzy szukają prostego i lekkiego, a jednocześnie w pełni funkcjonalnego narzędzia do testowania obciążenia,
  • zespołów, które chcą zintegrować testowanie z istniejącymi przepływami pracy deweloperskiej i strumieniami CI/CD.

Szkolenie

Chcesz dowiedzieć się więcej o korzystaniu z k6 w praktyce? Weź udział w naszym szkoleniu Testy wydajnościowe w k6.

Najbliższy termin szkolenia 6-8 lutego 2023 w formie online. Zapisz się na szkolenie tutaj.


 

Źródła:
https://k6.io/blog/k6-vs-jmeter/

To powinno Cię zainteresować