SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Jõudluse analüüs ja häälestamine on võimas tööriist jõudluse vastavuse kontrollimiseks klientide jaoks.

Jõudluse analüüsi saab kasutada programmi kitsaskohtade testimiseks, rakendades teaduslikku lähenemist häälestamise katsete kontrollimisel. See artikkel määratleb üldise lähenemise jõudluse analüüsimiseks ja häälestamiseks, kasutades näiteks Go veebiserverit.

Go sobib siinkohal väga hästi, kuna sellel on profileerimistööriistad pprof standardteegis.

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Strateegia

Loome kokkuvõtliku loendi meie struktuursest analüüsist. Püüame kasutada andmeid otsuste tegemiseks, mitte teha muudatusi intuitiivsetest või oletustel põhinevatest teadmistest. Selleks teeme järgmist:

  • Määratleme optimeerimise piirid (nõuded);
  • Kalkuleerime süsteemi tehingukoormuse;
  • Teeme testi (loodud andmed);
  • Kasutame jälgimist;
  • Analüüsime - kas kõik nõuded on täidetud?
  • Häälestame teaduslikult, teeme hüpoteesi;
  • Teeme eksperimendi selle hüpoteesi kontrollimiseks.

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Lihtsa HTTP-serveri arhitektuur

Selles artiklis kasutame väikest HTTP-serverit Golangis. Kõik artiklis olev kood on saadaval siin.

Analüüsitav rakendus on HTTP-server, mis küsib Postgresql'i igal päringul. Täiendavalt on olemas Prometheus, node_exporter ja Grafana rakenduse ja süsteemi mõõdikute kogumiseks ja kuvamiseks.

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Lihtsustamise huvides oletame, et horisontaalse skaleerimise (ja arvutuste lihtsustamiseks) puhul käivitatakse iga teenus ja andmebaas koos:

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Määratleme eesmärgid

Sellel etapil määratleme eesmärgi. Mida me üritame analüüsida? Kuidas me saame teada, millal on aeg lõpetada? Selles artiklis eeldame, et meil on kliendid ja et meie teenus töötleb 10 000 päringut sekundis.

Uues Google SRE raamat käsitleb üksikasjalikult valimise ja modelleerimise viise. Teeme samuti, ehitame mudeleid:

  • Viivitus: 99% päringutest peab täituma vähem kui 60 ms jooksul;
  • Kulu: teenus peab tarbima minimaalset summat raha, mis tundub mõistliku võimalikuna. Selleks maksimeerime läbilaskevõime;
  • Ressursside planeerimine: on vajalik mõista ja dokumenteerida, kui palju rakenduse koopiaid on vaja käivitada, sealhulgas üldine skaleerimisfunktsioon, samuti kui palju koopiaid on vajalik algsete koormusnõuete täitmiseks ning üleliigsuse tagamiseks. ülejääk n+1.

Läbivaatamine võib vajada optimeerimist koos analüüsiga, kuid läbilaskevõimet tuleb kindlasti analüüsida. SRE protsessi SLO kasutamisel tuleneb läbilaskenõue kliendilt või ärilt, mida esindab tooteomanik. Ja meie teenus täidab seda kohustust kohe alguses ilma igasuguste seadistusteta!

Seadistame testkeskkonna

Testkeskkonna abil saame süsteemile doseeritud koormuse anda. Tulemuste analüüsimiseks luuakse veebiteenuse jõudluse andmed.

Tehingukoormus

See keskkond kasutab Vegeta kohandatud HTTPS päringute sageduse genereerimiseks, kuni see peatatakse:

$ make load-test LOAD_TEST_RATE=50
echo "POST http://localhost:8080" | vegeta attack -body tests/fixtures/age_no_match.json -rate=50 -duration=0 | tee results.bin | vegeta report

Jälgimine

Koormuse ajal rakendatakse tehingukoormust. Lisaks rakenduse metrikatele (päringute arv, vastuse viivitus) ja operatsioonisüsteemi (mälu, CPU, IOPS) käivitatakse rakenduse profileerimine, et mõista, kus võivad esineda probleemid, samuti kuidas protsessori aega tarbitakse.

Profileerimine

Profileerimine on mõõtmise tüüp, mis võimaldab näha, kuhu protsessori aeg rakenduse töö ajal läheb. See aitab määrata, kus Just ja kui palju protsessori aega kulub:

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Need andmed saavad analüüsi käigus olla kasulikud, et saada ülevaade tarbetult kulutatud protsessori ajast ja teostatavast asjatust töödest. Go (pprof) suudab genereerida profiile ja visualiseerida neid leekgraafikuna, kasutades standardset tööriistakomplekti. Räägin nende kasutamisest ja seadistamise juhendist allpool artiklis.

Teostamine, jälgimine, analüüs.

Vi vi viib eksperiment. Jätkame täitmist, jälgimist ja analüüsimist, kuni jõuame rahuldava jõudluse tasemeni. Valime juhuslikult madala koormuse taseme, et rakendada seda esimeste tähelepanekute saamiseks. Iga järgmise sammuga suurendame koormust teatud skaleerimisfaktoriga, mis on valitud teatud vahemikus. Iga koormustest tehakse taotluste arvu reguleerimisega. make load-test LOAD_TEST_RATE=X.

50 taotlust sekundis

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Pöörake tähelepanu kahele ülemisele graafikule. Vasakul ülal on näha, et meie rakendus töötleb 50 taotlust sekundis (nii ta arvab), ja paremal ülal on iga taotluse kestus. Need kaks parameetrit aitavad meil vaadata ja analüüsida: kas jääme oma jõudlurpiiridesse või mitte. Graafikul olev punane joon HTTP taotluse latentsus näitab SLO-d 60 ms. Joone järgi on näha, et oleme oma maksimaalse vastuseajaga palju allpool.

Vaadates kulusid:

10000 taotlust sekundis / 50 taotlust serveri kohta = 200 serverit + 1

Me saame seda näitajat endiselt parandada.

500 taotlust sekundis

Huvitavamad asjad hakkavad toimuma, kui koormus tõuseb 500 taotlusele sekundis:

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Jällegi on vasakul ülal graafik selge, et rakendus registreerib tavapärast koormust. Kui see pole nii — on serveris, kus rakendus töötab, probleem. Paremal ülal olev vastuse latentsuse graafik näitab, et 500 taotlust sekundis on viinud vastuse latentsuse 25–40 ms-ni. 99. percenti jääb endiselt kenasti SLO-d 60 ms sisse.

Kulude küljest:

10000 taotlust sekundis / 500 taotlust serveri kohta = 20 serverit + 1

Seda saaendiselt parandada.

1000 taotlust sekundis

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Suurepärane käivitamine! Rakendus näitab, et töötles 1000 taotlust sekundis, kuid latentsuse piir oli SLO poolest ületatud. Seda näeb paremal ülal asuva graafiku p99 joone järgi. Kuigi p100 joon on palju kõrgem, on reaalsed latentsused kõrgemad kui maksimaalne 60 ms. Sukeldume profileerimisse, et aru saada, mida rakendus tegelikult teeb.

Profileerimine

Profileerimise jaoks seame koormuse 1000 taotlusele sekundis, seejärel kasutame pprof andmete kogumiseks, et teada saada, kus rakendus kulutab protsessorite aega. Seda saab teha HTTP lõpp-punkti aktiveerimisega. pprof, mille pärast koormuse ajal salvestada tulemused curl'i abil:

$ curl http://localhost:8080/debug/pprof/profile?seconds=29 > cpu.1000_reqs_sec_no_optimizations.prof

Tulemusi saab kuvada järgmiselt:

$ go tool pprof -http=:12345 cpu.1000_reqs_sec_no_optimizations.prof

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Graafik näitab, kus ja kui palju rakendus töötleb protsessori aega. Kirjeldus autorilt Brendan Gregg:

X teljel on stacki profiil, järjestatud tähestikku (see ei ole aeg), Y telg näitab stacki sügavust, arvestades nullist [top]. Iga ristkülik on stacki kaader. Mida laiem on kaader, seda sagedamini see esineb stackides. Ülal on CPU-le rakendatav, allpool on alamsüsteemid. Värvid, üldiselt, ei tähenda midagi ja on lihtsalt valitud juhuslikult kaadrite eristamiseks.

Analüüs — hüpotees

Seadistamiseks keskendume katsete tegemisele, et leida tarbetud protsessori ajakulu. Otsime suurimaid tarbetu kulu allikaid ja eemaldame need. Kuna profiilimine avab üsna täpselt, kus rakendus oma protsessori aega kulutab, võib olla vajalik see protsess mitu korda läbi viia, samuti tuleb muuta rakenduse lähtekoodi, testid uuesti käivitada ja jälgida, et jõudlus läheneb seatud eesmärgile.

Järgides Brendan Greggi soovitusi, loeme graafikut ülahulgast alla. Iga rida näitab stacki kaadrit (funktsiooni kutsumine). Esimene rida on programmi sisenemispunkt, kõigi teiste kutsumiste vanem (teisisõnu, kõik teised kutsumised sisaldavad seda oma stackis). Järgmine rida on juba erinev:

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Kui hiirekursor funktsiooni nimele graafikul liigutada, kuvatakse aeg, kui kaua see oli stackis silumise ajal. Funktsioon HTTPServe viibis seal 65% aega, teised funktsioonid runtime, runtime.mcall, mstart ja gc, võtsid ülejäänud aja. Huvi pakkuv fakt: 5% kogu ajast kulutatakse DNS-i päringutele:

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Aadressid, mida programm otsib, kuuluvad Postgresql'ile. Klõpsame FindByAge:

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Huvitaval kombel näitab programm, et põhimõtteliselt on kolm peamist allikat, mis põhjustavad viivitusi: ühenduste avamine ja sulgemine, andmete pärimine ja andmebaasi ühendamine. Graafik näitab, et DNS-i päringud, ühenduste avamine ja sulgemine võtavad umbes 13% kogu täitmisaegadest.

Hüpotees: Ühenduste taaskasutamine ühenduste basseiniga peaks vähendama ühe HTTP päringu aega, võimaldades suuremat läbilaskevõimet ja madalamaid latentsuseid..

Rakenduse seadistamine - eksperiment.

Uuendame lähtekoodi, proovime eemaldada iga päringu jaoks PostgreSQL ühenduse. Esimene variant - kasutamine. ühenduste basseini. rakenduse tasemel. Selles eksperimendis me seadistame. ühenduste basseini SQL draiveri abil Go jaoks:

db, err := sql.Open("postgres", dbConnectionString)
db.SetMaxOpenConns(8)

if err != nil {
   return nil, err
}

Täideviimine, jälgimine, analüüs.

Pärast testimise taaskäivitamist 1000 päringuga sekundis on näha, et p99 latentsused on normaliseerunud SLO 60ms juures!

Kuidas on hinnaga?

10000 päringut sekundis / 1000 päringut serveri kohta = 10 serverit + 1.

Teeme veel paremini!

2000 päringut sekundis.

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Koormuse kahekordistamine näitab sama, vasak ülemine diagramm näitab, et rakendus suudab töödelda 2000 päringut sekundis, p100 alla 60ms, p99 vastab SLO-le.

Kulude küljest:

10000 päringut sekundis / 2000 päringut serveri kohta = 5 serverit + 1.

3000 päringut sekundis.

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Siin suudab rakendus töödelda 3000 päringut p99 latentsusega alla 60ms. SLO ei ole rikutud ja hind kehtestatakse järgmiselt:

10000 päringut sekundis / 3000 päringut serveri kohta = 4 serverit + 1. (autor ümardas ülespoole, tõlkija märkus)

Proovime veel ühte analüüsiringi.

Analüüs — hüpotees

Kogume ja kuvatakse rakenduse tõrkeotsingu tulemused 3000 päringuga sekundis:

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Endiselt kulub 6% ajast ühenduste loomisele. Ühenduste basseini seadistamine parandas jõudlust, kuid on endiselt näha, et rakendus jätkab uute ühenduste loomist andmebaasiga.

Hüpotees: Ühendused, vaatamata basseini olemasolule, visatakse endiselt tagasi ja puhastatakse, seega peab rakendus neid uuesti seadistama. Ootel ühenduste arvu seadmine bassaini suurusele peaks aitama latentsust vähendada, minimeerides aega, mis rakendusel kulub ühenduse loomisele..

Rakenduse seadistamine - eksperiment.

Proovime seadistada MaxIdleConns võrdseks basseini suurusega (ka kirjeldatud siin):

db, err := sql.Open("postgres", dbConnectionString)
db.SetMaxOpenConns(8)
db.SetMaxIdleConns(8)
if err != nil {
   return nil, err
}

Täideviimine, jälgimine, analüüs.

3000 päringut sekundis.

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

p99 alla 60ms oluliselt madalama p100-ga!

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Flame graphi kontrollimine näitab, et ühenduse seadmine ei ole enam märgatav! Kontrollime lähemalt. pg(*conn).query — samuti ei märka siin ühenduse seadmist.

SRE: Sooritusanalüüs. Lihtsa veebi serveri seadistamise meetod Go abil

Kokkuvõte

Jõudluse analüüs on kriitiline, et mõista, kas kliendi ootused ja mittefunktsionaalsed nõuded on täidetud. Analüüs, võrreldes tähelepanekuid klientide ootustega, võib aidata kindlaks teha, mis on vastuvõetav ja mis mitte. Go pakub tõhusaid tööriistu, mis on integreeritud standardraamatukokku, et muuta analüüs lihtsaks ja kergesti ligipääsetavaks.

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster