SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Гүйцэтгэлийн шинжилгээ, тааруулах нь үйлчлүүлэгчдийн гүйцэтгэлийн нийцлийг шалгах хүчирхэг хэрэгсэл юм.

Гүйцэтгэлийн шинжилгээг тааруулах туршилтыг турших шинжлэх ухааны аргыг ашиглан хөтөлбөрт саад бэрхшээл байгаа эсэхийг шалгахад ашиглаж болно. Энэ нийтлэл нь жишээ болгон Go вэб серверийг ашиглан гүйцэтгэлийн дүн шинжилгээ хийх, тааруулах ерөнхий хандлагыг тодорхойлдог.

Go програм нь профайл хийх хэрэгслүүдтэй тул энд онцгой сайн байдаг pprof стандарт номын санд.

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Стратеги

Бүтцийн шинжилгээнд зориулж хураангуй жагсаалтыг гаргацгаая. Бид зөн совин, таамаглал дээр тулгуурлан өөрчлөлт оруулахын оронд шийдвэр гаргахдаа зарим өгөгдлийг ашиглахыг хичээх болно. Үүнийг хийхийн тулд бид үүнийг хийх болно:

  • Бид оновчлолын хил хязгаарыг (шаардлага) тодорхойлдог;
  • Бид системийн гүйлгээний ачааллыг тооцдог;
  • Бид туршилтыг гүйцэтгэдэг (өгөгдөл үүсгэх);
  • Бид ажиглаж байна;
  • Бид дүн шинжилгээ хийдэг - бүх шаардлага хангагдсан уу?
  • Бид үүнийг шинжлэх ухааны үндэслэлтэйгээр тогтоож, таамаглал дэвшүүлэх;
  • Энэ таамаглалыг шалгахын тулд бид туршилт хийдэг.

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Энгийн HTTP серверийн архитектур

Энэ нийтлэлд бид Голанг дахь жижиг HTTP серверийг ашиглах болно. Энэ нийтлэлийн бүх кодыг олж болно энд.

Шинжилгээ хийж буй програм нь хүсэлт бүрээр Postgresql-г санал асуулга явуулдаг HTTP сервер юм. Нэмж дурдахад Prometheus, node_exporter, Grafana программ болон системийн хэмжигдэхүүнүүдийг цуглуулж харуулах зориулалттай.

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Хялбаршуулахын тулд бид хэвтээ масштабын хувьд (мөн тооцооллыг хялбарчлах) үйлчилгээ болон мэдээллийн сан бүрийг хамтад нь байрлуулна гэж үзэж байна:

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Зорилгоо тодорхойлох

Энэ үе шатанд бид зорилгоо шийддэг. Бид юуг шинжлэх гэж байна вэ? Хэзээ дуусах цаг болсныг бид яаж мэдэх вэ? Энэ нийтлэлд бид үйлчлүүлэгчидтэй бөгөөд манай үйлчилгээ секундэд 10 хүсэлтийг боловсруулах болно гэж төсөөлөх болно.

В Google SRE ном Сонгох, загварчлах аргуудыг нарийвчлан авч үзсэн болно. Үүнтэй ижил зүйлийг хийж, загваруудыг бүтээцгээе:

  • Хоцролт: Хүсэлтийн 99% нь 60 мс-ээс бага хугацаанд хийгдэх ёстой;
  • Зардал: Үйлчилгээ нь боломжийн гэж үзсэн хамгийн бага хэмжээний мөнгө зарцуулах ёстой. Үүнийг хийхийн тулд бид дамжуулах чадварыг дээд зэргээр нэмэгдүүлэх;
  • Чадавхийг төлөвлөх: Аппликейшны хэдэн тохиолдлыг ажиллуулах шаардлагатай, үүнд ерөнхий масштабын функц, анхны ачаалал болон нөөцийн шаардлагыг хангахын тулд хичнээн тохиолдол шаардлагатайг ойлгох, баримтжуулах шаардлагатай. илүүдэл n+1.

Хоцролт нь дүн шинжилгээ хийхээс гадна оновчлолыг шаардаж болох ч дамжуулах чадварыг тодорхой шинжлэх шаардлагатай. SRE SLO процессыг ашиглах үед хойшлуулах хүсэлт нь бүтээгдэхүүн эзэмшигчийн төлөөлөл болсон үйлчлүүлэгч эсвэл бизнесээс ирдэг. Мөн манай үйлчилгээ энэ үүргээ анхнаасаа ямар ч тохиргоогүйгээр биелүүлэх болно!

Туршилтын орчинг бүрдүүлэх

Туршилтын орчны тусламжтайгаар бид системдээ хэмжсэн ачааллыг байрлуулах боломжтой болно. Шинжилгээ хийхийн тулд вэб үйлчилгээний гүйцэтгэлийн талаархи мэдээллийг бий болгоно.

Гүйлгээний ачаалал

Энэ орчныг ашигладаг Ургамал зогсоох хүртэл өөрчлөн HTTP хүсэлтийн хувь хэмжээг бий болгохын тулд:

$ 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

Ажиглалт

Гүйлгээний ачааллыг ажиллах үед хэрэглэнэ. Аппликешн (хүсэлтийн тоо, хариултын хоцролт) болон үйлдлийн систем (санах ой, CPU, IOPS) хэмжүүрээс гадна хаана асуудалтай байгаа болон CPU-ийн цаг хэрхэн зарцуулагдаж байгааг ойлгохын тулд програмын профайлыг ажиллуулна.

Профайл хийх

Профайл үүсгэх нь програм ажиллаж байх үед CPU-ийн цаг хаана байгааг харах боломжийг олгодог хэмжилтийн төрөл юм. Энэ нь процессорын цагийг хаана, хэр их зарцуулж байгааг тодорхойлох боломжийг танд олгоно.

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Энэхүү өгөгдлийг дүн шинжилгээ хийх явцад CPU-ийн дэмий зарцуулсан цаг, шаардлагагүй ажлын талаар ойлголттой болохын тулд ашиглаж болно. Go (pprof) нь стандарт хэрэгсэл ашиглан профайл үүсгэж, тэдгээрийг галын график хэлбэрээр дүрслэх боломжтой. Би тэдний хэрэглээ, тохиргооны гарын авлагын талаар өгүүллийн дараа ярих болно.

Гүйцэтгэл, ажиглалт, дүн шинжилгээ.

Туршилт хийцгээе. Гүйцэтгэлдээ сэтгэл хангалуун болтол нь хийж, ажиглаж, дүн шинжилгээ хийнэ. Анхны ажиглалтын үр дүнг авахын тулд дур мэдэн бага ачааллын утгыг сонгоцгооё. Дараагийн алхам бүрт бид ачааллыг тодорхой хэмжээний өөрчлөлтөөр сонгосон тодорхой масштабын хүчин зүйлээр нэмэгдүүлэх болно. Ачааллын туршилтын гүйлт бүрийг хүсэлтийн тоог тохируулан гүйцэтгэдэг. make load-test LOAD_TEST_RATE=X.

Секундэд 50 хүсэлт

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Эхний хоёр графикт анхаарлаа хандуулаарай. Зүүн дээд талд манай програм секундэд 50 хүсэлтийг боловсруулдаг (энэ нь бодож байгаа) бөгөөд баруун дээд талд хүсэлт бүрийн үргэлжлэх хугацааг харуулж байна. Энэ хоёр параметр нь бидний гүйцэтгэлийн хязгаарт байгаа эсэх, дүн шинжилгээ хийхэд тусалдаг. График дээрх улаан шугам HTTP хүсэлтийн хоцролт 60 мс-д SLO-г харуулдаг. Энэ шугам нь бид хамгийн дээд хариу өгөх хугацаанаас хамаагүй доогуур байгааг харуулж байна.

Зардлын талыг харцгаая:

Секундэд 10000 хүсэлт / сервер бүрт 50 хүсэлт = 200 сервер + 1

Бид энэ үзүүлэлтийг сайжруулах боломжтой хэвээр байна.

Секундэд 500 хүсэлт

Ачаалал нь секундэд 500 хүсэлт авах үед илүү сонирхолтой зүйлс тохиолдож эхэлдэг:

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Дахин хэлэхэд, зүүн дээд талын графикаас програм нь хэвийн ачааллыг бүртгэж байгааг харж болно. Хэрэв тийм биш бол програм ажиллаж байгаа серверт асуудал байна. Хариултын хоцрогдлын график нь баруун дээд буланд байрладаг бөгөөд секундэд 500 хүсэлт гарвал хариу 25-40 мс хоцорсныг харуулж байна. 99-р хувь нь дээр сонгосон 60ms SLO-д тохирсон хэвээр байна.

Зардлын хувьд:

Секундэд 10000 хүсэлт / сервер бүрт 500 хүсэлт = 20 сервер + 1

Бүх зүйлийг сайжруулах боломжтой хэвээр байна.

Секундэд 1000 хүсэлт

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Гайхалтай хөөргөх! Аппликешн нь секундэд 1000 хүсэлтийг боловсруулсныг харуулж байгаа боловч саатлын хязгаарыг SLO зөрчсөн байна. Үүнийг баруун дээд график дахь p99 мөрөнд харж болно. p100 шугам нь хамаагүй өндөр байгаа хэдий ч бодит саатал дээд тал нь 60ms-ээс өндөр байна. Аппликешн яг юу хийдэг болохыг олж мэдэхийн тулд профайл руу шумбаж үзье.

Профайл хийх

Профайл үүсгэхийн тулд бид ачааллыг секундэд 1000 хүсэлт болгож, дараа нь ашиглана pprof Програм нь CPU-ийн цагийг хаана зарцуулж байгааг олж мэдэхийн тулд өгөгдөл цуглуулах. Үүнийг HTTP төгсгөлийн цэгийг идэвхжүүлснээр хийж болно pprof, дараа нь ачаалалтай үед curl ашиглан үр дүнг хадгална уу:

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

Үр дүнг дараах байдлаар харуулж болно.

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

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

График нь програм CPU-ийн цагийг хаана, хэр их зарцуулж байгааг харуулж байна. -ийн тайлбараас Брендан Грегг:

X тэнхлэг нь цагаан толгойн үсгийн дарааллаар эрэмбэлэгдсэн стекийн профайлын хүн ам юм (энэ нь цаг хугацаа биш), Y тэнхлэг нь [дээд] тэгээс эхлэн тоолох стекийн гүнийг харуулдаг. Тэгш өнцөгт бүр нь стек хүрээ юм. Хүрээ нь илүү өргөн байх тусам стекүүдэд илүү олон удаа байдаг. Дээр байгаа зүйл нь CPU дээр ажилладаг бөгөөд доор байгаа нь хүүхэд элементүүд юм. Өнгө нь ихэвчлэн юу ч биш, харин хүрээг ялгахын тулд санамсаргүй байдлаар сонгогддог.

Шинжилгээ - таамаглал

Тохируулахын тулд бид CPU-ийн дэмий зарцуулсан цагийг олохыг хичээх болно. Бид ашиггүй зардлын хамгийн том эх үүсвэрийг хайж, тэдгээрийг арилгах болно. Профайл нь тухайн программ процессорын цагаа яг хаана зарцуулж байгааг маш нарийн харуулдаг тул та үүнийг хэд хэдэн удаа хийх шаардлагатай болохоос гадна програмын эх кодыг өөрчилж, туршилтуудыг дахин ажиллуулж, гүйцэтгэл зорилтот түвшинд ойртож байгааг харах хэрэгтэй болно.

Брендан Греггийн зөвлөмжийн дагуу бид графикийг дээрээс доош унших болно. Мөр бүр нь стекийн хүрээ (функцын дуудлага) харуулдаг. Эхний мөр нь програм руу нэвтрэх цэг, бусад бүх дуудлагын эх (өөрөөр хэлбэл, бусад бүх дуудлагад үүнийг стек дээрээ байлгах болно). Дараагийн мөр аль хэдийн өөр байна:

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Хэрэв та график дээрх функцын нэрэн дээр курсорыг аваачих юм бол дибаг хийх явцад стек дээр байсан нийт хугацаа харагдана. HTTPServe функц нь бусад ажиллах үеийн функцүүдийн 65% нь байсан runtime.mcall, mstart и gc, үлдсэн хугацааг зарцуулсан. Хөгжилтэй баримт: Нийт цагийн 5% нь DNS асуулгад зарцуулагддаг.

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Програмын хайж буй хаягууд нь Postgresql-д харьяалагддаг. Дээр товшино уу FindByAge:

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Сонирхолтой нь уг программ нь зарчмын хувьд холболтыг нээх, хаах, өгөгдөл хүсэх, өгөгдлийн сантай холбогдох гэсэн гурван үндсэн эх сурвалжийг саатуулдаг болохыг харуулж байна. Графикаас харахад DNS хүсэлт, нээх, хаах холболтууд нь нийт гүйцэтгэлийн 13 орчим хувийг эзэлдэг.

Таамаглал: Холболтыг нэгтгэх ашиглан дахин ашиглах нь нэг HTTP хүсэлтийн хугацааг багасгаж, илүү өндөр дамжуулалт, хоцролтыг багасгах боломжийг олгоно..

Програмыг тохируулах - туршилт

Бид эх кодыг шинэчилж, хүсэлт бүрт Postgresql холболтыг арилгахыг оролдоно уу. Эхний сонголт бол ашиглах явдал юм холболтын сан хэрэглээний түвшинд. Энэ туршилтанд бид үүнийг тохируулцгаая Go for sql драйвер ашиглан холболтын нэгтгэл:

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

if err != nil {
   return nil, err
}

Гүйцэтгэл, ажиглалт, дүн шинжилгээ

Туршилтыг секундэд 1000 хүсэлтээр дахин эхлүүлсний дараа p99-ийн хоцролтын түвшин 60 мс-ийн SLO-ээр хэвийн байдалдаа орсон нь тодорхой байна!

Ямар үнэтэй вэ?

Секундэд 10000 хүсэлт / сервер бүрт 1000 хүсэлт = 10 сервер + 1

Үүнийг илүү сайн хийцгээе!

Секундэд 2000 хүсэлт

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Ачааллыг хоёр дахин нэмэгдүүлэх нь ижил зүйлийг харуулж байна, зүүн дээд график нь програм нь секундэд 2000 хүсэлтийг боловсруулах чадвартай, p100 нь 60 мс-ээс бага, p99 нь SLO-г хангаж байгааг харуулж байна.

Зардлын хувьд:

Секундэд 10000 хүсэлт / сервер бүрт 2000 хүсэлт = 5 сервер + 1

Секундэд 3000 хүсэлт

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Энд програм нь 3000 мс-ээс бага p99 хоцролттой 60 хүсэлтийг боловсруулах боломжтой. SLO-г зөрчөөгүй бөгөөд зардлыг дараахь байдлаар хүлээн авна.

Секундэд 10000 хүсэлт / сервер бүрт 3000 хүсэлт = 4 сервер + 1 (зохиогч тойрсон, ойролцоогоор. орчуулагч)

Өөр нэг дүн шинжилгээ хийж үзье.

Шинжилгээ - таамаглал

Бид програмыг дибаг хийх үр дүнг секундэд 3000 хүсэлтээр цуглуулж харуулдаг.

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Цагийн 6% нь холболт тогтооход зарцуулагддаг. Усан санг тохируулах нь гүйцэтгэлийг сайжруулсан боловч програм нь мэдээллийн санд шинэ холболт үүсгэхээр үргэлжлүүлэн ажиллаж байгааг харж болно.

Таамаглал: Усан сан байгаа хэдий ч холболтууд тасарч, цэвэрлэгдсээр байгаа тул програмыг дахин тохируулах шаардлагатай. Хүлээгдэж буй холболтын тоог цөөрмийн хэмжээнд тохируулах нь програмын холболт үүсгэхэд зарцуулдаг хугацааг багасгах замаар хоцролтыг багасгахад тусална..

Програмыг тохируулах - туршилт

Суулгах гэж оролдож байна MaxIdleConns усан сангийн хэмжээтэй тэнцүү (мөн тайлбарласан энд):

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

Гүйцэтгэл, ажиглалт, дүн шинжилгээ

Секундэд 3000 хүсэлт

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

p99 нь 60ms-ээс бага, p100 хамаагүй бага!

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

Галын графикийг шалгах нь холболт нь мэдэгдэхээ больсон гэдгийг харуулж байна! Илүү дэлгэрэнгүй авч үзье pg(*conn).query - Энд холболт тогтоогдсоныг бид бас анзаардаггүй.

SRE: Гүйцэтгэлийн шинжилгээ. Go дахь энгийн вэб сервер ашиглан тохируулах арга

дүгнэлт

Гүйцэтгэлийн шинжилгээ нь хэрэглэгчийн хүлээлт болон функциональ бус шаардлагыг хангаж байгааг ойлгоход маш чухал юм. Хэрэглэгчийн хүлээлттэй ажиглалтыг харьцуулах замаар дүн шинжилгээ хийх нь юу нь хүлээн зөвшөөрөгдөх, юу нь болохгүйг тодорхойлоход тусална. Go нь шинжилгээг энгийн бөгөөд хүртээмжтэй болгодог стандарт номын санд суурилуулсан хүчирхэг хэрэгслээр хангадаг.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх