
Una dintre problemele cu care se confruntă frecvent vendorii de software multi-produs este duplicarea competențelor inginerilor — dezvoltatori, testeri și administratori de infrastructură — aproape în fiecare echipă. Aceasta se aplică și inginerilor costisitori — specialiști în testarea de încărcare.
În loc să își desfășoare atribuțiile directe și să își folosească experiența unică pentru a construi procesul de testare a încărcării, a alege metodologia, valorile optime ale metricilor și a scrie teste automate conform profilurilor de încărcare, inginerii sunt adesea nevoiți să dezvolte de la zero infrastructura de testare, să configureze instrumentele de încărcare, să le integreze în sistemele CI, să configureze monitorizarea și publicarea rapoartelor.
Soluțiile pentru anumite probleme organizaționale în testare, pe care le aplicăm în Positive Technologies, pot fi găsite în . În acest articol, voi discuta despre posibilitatea integrării testelor de încărcare în întregul pipeline CI prin conceptul de „testare de încărcare ca serviciu” (load testing as a service). Vei învăța cum și ce imagini Docker ale surselor de încărcare pot fi utilizate în pipeline-ul CI; cum să conectezi sursele de încărcare în proiectul tău CI folosind un șablon de build; cum arată un pipeline demo pentru a rula testele de încărcare și a publica rezultatele. Articolul poate fi util inginerilor de testare a software-ului și inginerilor de automatizare în CI, care s-au gândit la arhitectura sistemului lor de încărcare.
Esana conceptului
Conceptul de load testing as a service presupune capacitatea de a integra instrumentele de încărcare Apache JMeter, Yandex.Tank și cadrele proprii într-un sistem de integrare continuă la alegere. Exemplul demonstrativ va fi pentru GitLab CI, dar principiile sunt generale pentru toate sistemele CI.
Load testing as a service este un serviciu centralizat pentru efectuarea testării de încărcare. Testele de încărcare sunt lansate în pool-uri dedicate de agenți, publicarea rezultatelor se face automat în GitLab Pages, Influx DB și Grafana sau în sistemele de raportare a testelor (TestRail, ReportPortal etc.). Automatizarea și scalarea sunt realizate cât mai simplu — prin adăugarea și parametrizarea unui șablon obișnuit gitlab-ci.yml în proiectul GitLab CI.
Avantajul abordării constă în faptul că întreaga infrastructură CI, agenții de încărcare, imaginile Docker ale surselor de încărcare, pipeline-urile de testare și publicarea raporturilor sunt susținute de forțele unui departament centralizat de automatizare (ingenieri DevOps), iar inginerii de testare a încărcării se pot concentra asupra dezvoltării testelor și analizei rezultatelor acestora, fără a se ocupa de problemele de infrastructură.
Pentru simplificarea descrierii, vom presupune că aplicația sau serverul țintă s-au desfășurat și configurat în prealabil (acesta poate fi realizat prin scripturi automatizate pe Python, SaltStack, Ansible etc.). Atunci întreaga conceptie de testare a încărcării ca serviciu se încadrează în trei etape: preparare, testare, publicare de rapoarte. Mai multe detalii în schema (toate imaginile sunt clicabile):
Concepturi și definiții de bază în testarea încărcării
Atunci când efectuăm teste de încărcare, ne străduim să respectăm , folosind terminologia adecvată și metricile recomandate. Voi oferi o listă scurtă cu conceptele și definițiile de bază în testarea încărcării.
Agent de încărcare (load agent) — un mașină virtuală pe care va fi lansată aplicația — sursa de încărcare (Apache JMeter, Yandex.Tank sau un modul de încărcare personalizat).
Scopul testării (target) — un server sau o aplicație instalată pe server care va fi supusă încărcării.
Caz de testare (test case) — un set de pași parametrici: acțiunile utilizatorilor și reacțiile așteptate la aceste acțiuni, cu cererile și răspunsurile de rețea înregistrate, în funcție de parametrii specificați.
Profil sau plan de încărcare (profile) — în (p. 4.2.4, p. 43) profilurile de încărcare definesc metricile critica pentru testul specific și opțiunile de modificare a parametrilor de încărcare pe parcursul testului. Exemple de profiluri le puteți vedea în imagine.
Test (test) — un scenariu cu un set prestabilit de parametri.
Plan de testare (test-plan) — un set de teste și profilul de încărcare.
Executare de test (testrun) — o iterație a lansării unui test cu un scenariu de încărcare complet executat și un raport obținut.
Cerere de rețea (request) — cerere HTTP trimisă de agent către țintă.
Răspuns de rețea (response) — Răspunsul HTTP trimis de către destinație către agent.
Codul de răspuns HTTP (statusul răspunsurilor HTTP) — un cod standard de răspuns de la serverul aplicației.
Tranzacția (transaction) — ciclul complet 'cerere — răspuns'. O tranzacție este considerată de la începutul trimiterii cererii (request) până la finalizarea primirii răspunsului (response).
Starea tranzacției (transactions status) — dacă ciclul 'cerere – răspuns' s-a finalizat cu succes. Dacă în acest ciclu a existat orice eroare, întreaga tranzacție se consideră nereușită.
Timp de răspuns (latency) — timpul de la finalizarea trimiterii cererii (request) până la începutul primirii răspunsului (response).
Metrici de încărcare (metrics) — caracteristicile servicului încărcat și ale agentului de încărcare, definite în timpul testării de încărcare.
Metrici principale pentru măsurarea parametrilor de încărcare
Unele dintre cele mai utilizate și recomandate metrici în metodologie (pg. 36, 52) sunt prezentate în tabelul de mai jos. Metrici similari pentru agent și destinație sunt specificați pe aceeași linie.
Metrici pentru agentul de încărcare
Metrici pentru sistemul sau aplicația țintă, testate sub încărcare
Număr vCPU și memorie RAM,
Discul — caracteristicile 'hardware' ale agentului de încărcare
CPU, Memorie, utilizarea discului — dinamica încărcării procesorului, memoriei și discului
în timpul testării. De obicei, este măsurată în procente din
valorile maxim disponibile
Lățimea de bandă a rețelei (pe agentul de încărcare) — capacitatea de transmisie
a interfeței de rețea de pe server,
unde este instalat agentul de încărcare.
De obicei, este măsurată în biți pe secundă (bps)
Lățimea de bandă a rețelei(pe țintă) — lățimea de bandă a interfeței de rețea
de pe serverul țintă. De obicei, este măsurată în biți pe secundă (bps)
Utilizatori virtuali— numărul de utilizatori virtuli,
care pun în aplicare scenariile de încărcare și
imiți acțiuni reale ale utilizatorilor.
Starea utilizatorilor virtuali, Notați/Defecți/Total — numărul stărilor de succes și
defecțiunilor activității utilizatorilor virtuali
pentru scenariile de încărcare, precum și numărul lor total.
Se așteaptă în mod obișnuit ca toți utilizatorii să fi putut finaliza
toate sarcinile lor specificate în profilul de încărcare.
Orice eroare va însemna că și utilizatorul real nu va putea
să își rezolve sarcina când interacționează cu sistemul.
Cereri pe secundă (minut)— numărul de cereri de rețea pe secundă (sau pe minut).
O caracteristică importantă a agentului de încărcare: câte cereri poate genera.
De fapt, aceasta este o simulare a interacțiunii cu aplicația de către utilizatori virtuali
Răspunsuri pe secundă (minut)
— numărul de răspunsuri în rețea pe secundă (sau minut).
O caracteristică importantă a serviciului țintă: câte răspunsuri au fost generate
și trimise la cereri din
agenții de încărcare
Statutul răspunsurilor HTTP— numărul de coduri de răspuns diferite
de la serverul aplicației, primite de agenții de încărcare.
De exemplu, 200 OK înseamnă o interacțiune reușită,
iar 404 — că resursa nu a fost găsită
Întârzierea (timpul de răspuns) — timpul de la terminarea
trimiterii cererii (request) până la începutul primirii răspunsului (response).
De obicei, se măsoară în milisecunde (ms)
Timpul de răspuns pentru tranzacții— timpul unei tranzacții complete,
finalizarea ciclului «cerere — răspuns».
Acest timp este de la începutul trimiterii cererii (request)
până la finalizarea primirii răspunsului (response).
Timpul tranzacției poate fi măsurat în secunde (sau minute)
în mai multe moduri: se calculează minimul,
maximul, media și, de exemplu, percentilul 90.
Valorile minime și maxime sunt condiții extreme
ale performanței sistemului.
Percentilul nouăzeci este cel mai des utilizat,
deoarece arată majoritatea utilizatorilor,
care lucrează confortabil la limita performanței sistemului
Tranzacții pe secundă (minut) — numărul de tranzacții complete
pe secundă (minut),
adică câte cereri a reușit aplicația să primească și
să proceseze și să emită răspunsuri.
De fapt, aceasta este lățimea de bandă a sistemului
Statutul tranzacțiilor , Trecut / Eșuat / Total — numărul
de tranzacții reușite, eșuate și total.
Pentru utilizatorii reali, o tranzacție eșuată
va însemna de fapt
imposibilitatea de a lucra cu sistemul sub sarcină
Schema principială a testării de încărcare
Schema principială a testării de încărcare este foarte simplă și constă în trei etape principale, despre care am menționat deja: Pregătire — Test — Raport, adică pregătirea obiectivelor de testare și stabilirea parametrilor pentru sursele de încărcare, apoi executarea testelor de încărcare și, în final, generarea și publicarea raportului de testare.
Note despre schemă:
- QA.Tester — expert în testarea de încărcare,
- Target — aplicația țintă, pentru care trebuie să aflăm comportamentul său sub sarcină.
Clasificator de entități, etape și pași în schemă
Etape și pași
Ce se întâmplă
Ce există la intrare
Ce există la ieșire
Pregătire: etapa de pregătire pentru testare
LoadParameters
Sarcina și inițializarea
de către utilizator
parametrii de încărcare,
selectarea metricilor și
pregătirea planului de testare
(profilul de încărcare)
Parametrii personalizați pentru
inițializarea agentului de încărcare
Planul de testare
Scopul testării
VM
Implementarea în cloud
a mașinii virtuale cu
caracteristici necesare
Parametrii VM pentru agentul de încărcare
Scripturi de automatizare pentru
crearea VM-urilor
VM configurat în
cloud
Env
Configurația sistemului de operare și pregătirea
mediului pentru
funcționarea agentului de încărcare
Parametrii mediului pentru
agentul de încărcare
Scripturi de automatizare pentru
configurări ale mediului
Mediu pregătit:
OS, servicii și aplicații,
necesare pentru funcționare
agentul de încărcare
LoadAgents
Instalarea, configurarea și parametrizarea
agentului de încărcare.
Sau descărcarea imaginii docker cu
sursă de încărcare preconfigurată
Imagine docker pentru sursa de încărcare
(JMeter, JM sau framework personalizat)
Parametrii de configurare
agentul de încărcare
Agentul de încărcare configurat și gata
de lucru
Test: etapa de execuție a testelor de încărcare. Sursele sunt agenții de încărcare, desfășurați în grupuri dedicate de agenți pentru GitLab CI
Load
Startul agentului de încărcare
cu planul de testare selectat
și parametrii de încărcare
Parametrii personalizați
pentru inițializare
agentul de încărcare
Planul de testare
Scopul testării
Jurnale de execuție
testelor de încărcare
Jurnale de sistem
Dinamică a modificării metricilor obiectivului și agentului de încărcare
RunAgents
Executarea de către agentul de
încărcare a scenariilor de testare
conform
profilului de încărcare
Interacțiunea agentului de încărcare
cu obiectivul de testare
Planul de testare
Scopul testării
Jurnale
Colectarea de jurnale „neprelucrate”
în timpul testării de încărcare:
înregistrări ale acțiunilor agentului de încărcare,
starea obiectivului de testare
și VM-ul pe care este desfășurat agentul
Jurnale de execuție
testelor de încărcare
Jurnale de sistem
Metrics
Colectarea de metrici „neprelucrate” în timpul testării
Dinamică a modificării metricilor obiectivului
și agentului de încărcare
Report: etapa de pregătire a raportului de testare
Generator
Prelucrarea metricelor
colectate de sistemul de încărcare și
sistemul de monitorizare „neprelucrate”
metrici și jurnale
Generarea raportului într-un
format ușor de înțeles,
posibil cu elemente
de analiză
Jurnale de execuție
testelor de încărcare
Jurnale de sistem
Dinamică a modificării metricilor
obiectivului și agentului de încărcare
Jurnale „neprelucrate” prelucrate
într-un format adecvat pentru
export în stocuri externe
Raport static despre încărcare,
adecvat pentru analiză umană
Publicați
Publicarea raportului
despre încărcare
testare în extern
serviciu
Log-urile „brute” procesate
într-un format adecvat
pentru export în externe
un stocare
Raportele salvate în extern
stocare despre
încărcare, adecvate
pentru analiza umană
Conectarea surselor de încărcare în șablonul CI
Să trecem la partea practică. Vreau să arăt cum în anumite proiecte din compania am implementat concepția de testare a încărcărilor ca serviciu.
Inițial, prin intermediul inginerilor noștri DevOps, am creat în GitLab CI un grup dedicat de agenți pentru a rula teste de încărcare. Pentru a nu-i confunda în șabloane cu alte grupuri, cum ar fi cele de compilare, am adăugat etichete pentru acești agenți, : load. Se pot folosi orice alte etichete relevante. Acestea sunt stabilite GitLab CI Runners.
Cum putem determina puterea necesară pentru hardware? Caracteristicile agenților de încărcare — un număr suficient de vCPU, RAM și Disk — pot fi calculate pe baza faptului că pe agent trebuie să fie rulate Docker, Python (pentru Yandex.Tank), agentul GitLab CI, Java (pentru Apache JMeter). Pentru Java sub JMeter se recomandă, de asemenea, utilizarea a minimum 512 MB RAM și, ca limită superioară, .
Astfel, pe baza experienței noastre, recomandăm utilizarea pentru agenții de încărcare de cel puțin: 4 vCPU, 4 GB RAM, 60 GB SSD. Lățimea de bandă a plăcii de rețea este determinată pe baza cerințelor profilului de încărcare.
În principal, folosim două surse de încărcare — imagini Docker Apache JMeter și Yandex.Tank.
este un instrument open-source dezvoltat de Yandex pentru efectuarea testării sarcinilor de lucru. La baza arhitecturii sale modulare se află un generator HTTP performant, asincron, bazat pe hit-uri numit Phantom. Tankează are un monitor integrat al resurselor serverului testat prin protocolul SSH, poate opri automat testul în condiții specificate, poate afișa rezultatele atât în consolă, cât și sub formă de grafice, iar la el se pot conecta module proprii pentru extinderea funcționalității. Apropo, am folosit Tank-ul când nu era încă mainstream. În articolul „se poate citi istoria despre cum în 2013 am efectuat testarea sarcinilor de lucru — unul dintre produsele companiei noastre.
— este un instrument open-source pentru efectuarea testelor de încărcare de la Apache. Poate fi utilizat la fel de bine atât pentru testarea aplicațiilor web statice, cât și pentru cele dinamice. JMeter suportă o multitudine de protocoale și metode de interacțiune cu aplicațiile: HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET etc.), servicii web SOAP / REST, FTP, TCP, LDAP, SMTP(S), POP3(S) și IMAP(S), baze de date prin JDBC, poate executa comenzi shell și lucra cu obiecte Java. JMeter dispune de un IDE pentru crearea, depanarea și executarea planurilor de testare. De asemenea, există un CLI pentru a lucra din linia de comandă a oricărui sistem de operare compatibil cu Java (Linux, Windows, Mac OS X). Instrumentul poate genera dinamic un raport HTML despre testare.
Pentru a facilita utilizarea în cadrul companiei noastre și pentru a permite testerilor să modifice și să adauge mediul, am realizat construcții de imagini Docker pentru sursele de încărcare pe GitLab CI cu publicare în . Astfel, devine mai rapid și mai simplu să le conectăm în pipeline-uri pentru testele de încărcare. Cum să efectuezi un docker push în registry prin GitLab CI — consultați .
Fișierul Docker de bază pentru Yandex.Tank pe care l-am folosit este acesta:
Dockerfile
1 | FROM direvius/yandex-tank
2 | ENTRYPOINT [""]Iar pentru Apache JMeter acesta:
Dockerfile
1 | FROM vmarrazzo/jmeter
2 | ENTRYPOINT [""]Cum este organizat sistemul nostru de integrare continuă, puteți citi în articolul „».
Șablon și pipeline
Un exemplu de șablon pentru realizarea testelor de încărcare este disponibil în proiectul . În puteți citi instrucțiunile de utilizare a șablonului. În acel șablon (fișier ) există comentarii referitoare la responsabilitățile fiecărei etape.
Șablonul este foarte simplu și demonstrează cele trei etape de testare a încărcării, descrise mai sus în schemă: pregătire, testare și publicare a rapoartelor. Pentru aceasta sunt responsabile : Prepare, Test și Report.
- Etapa trebuie utilizată pentru configurarea preliminară a țintelor de testare sau pentru verificarea disponibilității acestora. Medii pentru sursele de încărcare nu trebuie să fie configurate, deoarece acestea sunt deja construite ca imagini Docker și disponibile în registrul Docker: este suficient să specificați versiunea dorită la etapa Test. Dar este posibil să le reconstruiți și să creați propriile imagini modificate.
- Etapa este utilizat pentru a indica sursa de încărcare, a lansă teste și a salva artefactele testării. Se poate alege orice sursă de încărcare: Yandex.Tank, Apache JMeter, propria sursă sau toate împreună. Pentru a dezactiva sursele nedorite, este suficient să comentați sau să eliminați job-ul. Punctele de intrare pentru sursele de încărcare:
- parametrii de lansare pentru Yandex.Tank sunt specificați în fișierul.,
- parametrii de lansare pentru Apache JMeter sunt specificați în fișierul .
Notă: șablonul de configurare a construcției este utilizat pentru a seta interacțiunea cu sistemul CI și nu presupune includerea logicii testelor. Pentru teste, se specifică punctul de intrare, unde se află script-ul bash de control. Modul de lansare a testelor, generarea rapoartelor și scenariile de testare trebuie să fie implementate de inginerii QA. În exemplul demonstrativ, pentru ambele surse de încărcare, ca test de bază este folosită cererea principală a paginii Yandex. Scenariile și parametrii testelor se află în directorul .
- La etapa trebuie să descrieți metodele de publicare a rezultatelor testării obținute în etapa Test, în depozite externe, de exemplu în GitLab Pages sau sisteme speciale de raportare. Pentru GitLab Pages este necesar ca, după încheierea testelor, directorul ./public să fie neîntărit și să conțină cel puțin fișierul index.html. Detalii despre modul de funcționare al serviciului GitLab Pages puteți citi .
Exemple despre cum să exportați datele:
- din JMeter în ,
- din Yandex.Tank în .
Instrucțiuni pentru configurarea publicației:
- statice HTML în ,
- în InfluxDB și apoi în .
În exemplul demonstrativ, pipeline-ul cu teste de încărcare și două surse de încărcare (una dintre ele poate fi dezactivată) arată astfel:
Apache JMeter poate genera singur raport HTML, iar acesta este mai rentabil de salvat în GitLab Pages prin mijloacele standard. Iată cum arată raportul Apache JMeter:
În exemplul demonstrativ pentru Yandex.Tank veți vedea doar în secțiunea pentru GitLab Pages. În timpul testării, Tank poate salva rezultatele în baza de date InfluxDB, iar de acolo acestea pot fi afișate, de exemplu, în Grafana (configurarea se face în fișierul ). Iată cum arată raportul Tank în Grafana:
Rezumat
În articol am discutat despre conceptul „testare de încărcare ca serviciu” (load testing as a service). Ideea principală constă în utilizarea infrastructurii unui grup preconfigurat de agenți de testare, imagini Docker pentru sursele de încărcare, sisteme de raportare și pipeline-ul care le leagă în GitLab CI bazat pe un șablon simplu .gitlab-ci.yml (exemplu ). Toate acestea sunt susținute de o echipă mică de ingineri automatizatori și replicate la cererea echipelor de produse. Sper că acest lucru vă va ajuta în pregătirea și implementarea unei scheme similare în compania dumneavoastră. Vă mulțumesc pentru atenție!
P. S. Vreau să le mulțumesc colegilor mei, Serghei Kurbanov și Nikolai Iusev, pentru ajutorul tehnic în implementarea conceptului de load testing as a service în compania noastră.
Autor: — adjunctul șefului departamentului de tehnologii și procese de dezvoltare (DevOps) la Positive Technologies
Sursa: habr.com
