TPS limitidan oshib ketish sababli serverning ishlamay qolishi
Ma’lumotlarni bortda yig‘ib, quruqlikdagi ma’lumotlar ko‘liga qayta uzatish uchun pipeline’ni sozlash jarayonida chegaraviy qiymatlarni sinashni talab qilgan vaziyatga duch keldik. Bortdagi pod’larda saqlangan xabarlarni quruqlikdagi ma’lumotlar ko‘liga qayta uzatish uchun xabarlar ikkita relay segmenti — EMQX va CCMD — orqali o‘tishi kerak edi, chunki bu segmentlarda soniyasiga qayta ishlay oladigan xabarlar soni, ya’ni TPS limiti, cheklangan edi.
Bir nechta kemalarda aloqa muhiti beqaror bo‘lgani sababli ma’lumotlar ko‘pincha yetib kelmasdi. Shu bois tizim ma’lumotlar ko‘lidan olinmagan barcha ma’lumotlarni batch processing orqali bir vaqtning o‘zida so‘raydigan qilib loyihalashtirilgan edi. Odatdagi trafik paytida hajm TPS limitidan ancha past bo‘lardi, biroq batch logikasi ishga tushadigan qisqa lahzalarda shu miqdordan bir necha baravar ko‘p xabar bir vaqtning o‘zida oqib kelardi. Agar o‘rtacha kiruvchi oqimga asoslanib loyihalashtirilgan pipeline bunday lahzalarga bardosh bera olmasa, relay segmentlaridagi serverlar ishlamay qolardi va hatto bitta xato ham qayd etilmasdan xabarlar jimgina yo‘qolardi.
Oxir-oqibat, biz bilishimiz kerak bo‘lgan narsa “Bu pipeline soniyasiga nechta xabarni qayta ishlay oladi?” emas, balki “To‘satdan keskin oqim yuzaga kelganda, u avval qayerda ishdan chiqadi va tiklanish uchun qancha vaqt ketadi?” degan savol edi. Uzoq vaqt davomida doimiy yuklamani ushlab turadigan an’anaviy load test bu savollarga javob bera olmasdi, shuning uchun Spike Test’ni tanladik.
Xo‘sh, Spike Test nima?
Test dizaynini batafsil ko‘rib chiqishdan oldin, Spike Test boshqa load testing turlaridan nimasi bilan farq qilishini aniqlab olish foydali. Load test’larni qo‘llanadigan yuklama shakliga ko‘ra keng ma’noda to‘rt turga bo‘lish mumkin. Load Test odatdagi qayta ishlashni tekshirish uchun kutilayotgan normal yuklamani doimiy darajada ushlab turadi. Stress Test tizim ishdan chiqadigan chegarani topish uchun yuklamani bosqichma-bosqich oshiradi. Soak Test esa vaqt o‘tishi bilan yuzaga keladigan memory leak yoki resurslarning tugashi kabi muammolarni aniqlash uchun past yuklamani uzoq vaqt davomida ushlab turadi.
Bunga qarama-qarshi ravishda, Spike Test qisqa vaqt ichida yuklamani tez oshiradi va keyin uni yana tez pasaytiradi. Uning boshqa usullardan hal qiluvchi farqi shundaki, u maksimal throughput’ning o‘ziga emas, balki tizimning to‘satdan yuz beradigan o‘zgarishlarga javobi va chidamliligiga e’tibor qaratadi. Unda yuklama keskin oshganda navbat qanchalik to‘planishi, xatolar darajasi va ma’lumotlar yo‘qolishi qaysi nuqtada boshlanishi hamda yuklama yo‘qolgach dastlabki holatga qaytish uchun qancha vaqt ketishi tekshiriladi.
Ta’rifiga ko‘ra, qayta uzatish trafigi spike shakliga ega. U odatdagi sharoitda past bo‘lib qoladi, faqat qayta ulanish yuz berganda tik ko‘tariladi va navbatda to‘plangan barcha xabarlar yuborilgach dastlabki darajasiga qaytadi. Agar haqiqiy trafik shunday shaklga ega bo‘lsa, mazmunli natijalar olish uchun test ham xuddi shu shaklda bo‘lishi kerak.

Qayta uzatish yo‘li va bottleneck
Sinovdan o‘tkazilgan yo‘l bortdagi pod’lardan boshlanib, EMQX va CCMD orqali quruqlikdagi ma’lumotlar ko‘ligacha davom etdi. Bortdagi pod’lar saqlangan xabarlarini EMQX’ga publish qilganda, CCMD ularni qabul qilib, quruqlikdagi segmentga relay qildi va u yerda xabarlar oxir-oqibat ma’lumotlar ko‘liga yuklandi. Bir nechta ketma-ket segmentlardan tashkil topgan pipeline’da umumiy throughput o‘rtacha qiymat bilan emas, balki yuqori chegarasi eng past bo‘lgan segment bilan belgilanadi. Bu yo‘lda bunday rolni TPS limiti qo‘llanadigan relay segmentlari bajardi.
Shuningdek, TPS limitidan oshib ketganda nimalar yuz berishi mumkinligini oldindan hujjatlashtirishimiz kerak edi. Ortiqcha trafik throttling qilinishi va kechikishlar to‘planishi mumkin edi; backpressure qo‘llanilguncha xabarlar navbatda to‘planishda davom etishi mumkin edi; eng yomon holatda esa ulanishlar uzilishi yoki xabarlar tashlab yuborilishi mumkin edi. Ayniqsa, xabarlar aslida ma’lumotlar ko‘liga yetib bormagan bo‘lsa ham, publish qiluvchi tomon ularni muvaffaqiyatli yuborilgan deb qayd etadigan holatlar muammoli edi. Bunday yo‘qotishlarni faqat publisher log’lariga qarab aniqlab bo‘lmagani uchun, publish qilingan xabarlar sonini oxir-oqibat qabul qilingan xabarlar soni bilan taqqoslash orqali tizimni tekshirish juda muhim edi.
Test dizayni
Spike Test uchta narsani tekshirish uchun mo‘ljallangan edi. Birinchidan, TPS limitidan oshib ketilganda qaysi segmentda va qanday ko‘rinishda muammolar yuzaga kelishi. Ikkinchidan, xabarlar yo‘qotilmasdan o‘ta oladigan amaliy yuqori chegara qayerdaligi. Uchinchidan, spike o‘tgach, navbatni bo‘shatish va tizimni normal holatga qaytarish uchun qancha vaqt ketishi.
Yuklama egri chizig‘i amaldagi qayta ulanish ssenariysini takrorlaydigan qilib ishlab chiqildi. Biz normal boshlang‘ich darajani qisqa vaqt ushlab turdik, so‘ng qisqa muddat ichida yuklamani vertikal ravishda maqsadli TPS’dan bir necha baravar yuqori qiymatgacha tez oshirdik, uni belgilangan vaqt davomida ushlab turdik va keyin tiklanish jarayonini kuzatish uchun boshlang‘ich darajaga tez tushirdik. Agar ramp-up davri juda uzun qilinsa, yuklama asta-sekin oshadi va test amalda Stress Test’ga aylanadi. Shu sababli ramp-up davrini ataylab qisqa saqlash muhim.
Har bir segment uchun observability metrikalarini alohida yig‘dik. Publish qiluvchi tomonda haqiqiy publish TPS’i hamda muvaffaqiyatli va muvaffaqiyatsiz javoblarni kuzatdik. Relay segmentlarida EMQX’ning inflight va queued message sonlari, shuningdek CCMD’ning qayta ishlash kechikishi va xatolar darajasini kuzatdik. Qabul qiluvchi tomonda esa ma’lumotlar ko‘li qabul qilgan xabarlar sonini tekshirdik. Bundan tashqari, har bir xabarga publish vaqti timestamp’i va sequence number’ini qo‘shdik, shunda end-to-end kechikish va yo‘qotish darajasini bir vaqtning o‘zida hisoblash mumkin bo‘ldi.
Spike Test’ni qanday o‘tkazish kerak
Spike Test’ni k6, JMeter va Gatling kabi load-testing vositalari yordamida o‘tkazish mumkin. Biroq maqsad TPS limitini tekshirish bo‘lsa, virtual user’lar sonini emas, soniyasiga yuboriladigan so‘rovlar sonini bevosita boshqara oladigan vositani tanlash muhim. Yuklama virtual user’lar soni asosida yaratilganda, javoblar sekinlashishi bilan haqiqiy publish tezligi pasayadi va shu tariqa tekshirilishi kerak bo‘lgan ortiqcha yuklama holatining o‘zi yuzaga kelmaydi.

k6’dan foydalanganda, bu maqsad uchun ramping-arrival-rate executor’i eng mos keladi. U stages yordamida har bir segment uchun maqsadli TPS’ni bevosita ko‘rsatish imkonini beradi, shuning uchun baseline va spike qismlarini istalgancha shakllantirish mumkin. Yetarli preAllocatedVUs va maxVUs ajratish orqali yuklama keskin oshgan paytda yangi virtual user’larni yaratish zarurati haqiqiy ramp-up’ni susaytirib qo‘yishining ham oldini olish mumkin. JMeter’da esa xuddi shunday egri chiziqni Ultimate Thread Group va Constant Throughput Timer’ni birlashtirish orqali yaratish mumkin.
Testni o‘tkazishda load generator’ning o‘zi bottleneck’ka aylanib qolmasligiga ishonch hosil qiling. Agar load generator target system bilan bir node’da ishlasa yoki connection pool yetarli bo‘lmasa, relay segmentlaridan oldin test vositasining o‘zi limitiga yetib qolishi va haqiqatdan farq qiladigan natijalar berishi mumkin. Shuningdek, spike tugashi bilan testni darhol yakunlamang. Backlog’dagi xabarlarni bo‘shatish hamda tiklanish jarayonini kuzatish uchun baseline holatini yana bir necha daqiqa saqlab turing.
Spike vaqtida qayta uzatish logikasida aniqlangan muammolar
Qayta ulanishdan keyin ayrim xabarlar yo‘qoladigan muammo asosida ishlab chiqilgan ssenariy yordamida Spike Test o‘tkazdik. TPS limitidan oshilgan nuqtadan boshlab ayrim xabarlar publish qiluvchi tomonda muvaffaqiyatli uzatilgan deb qayd etilganini, biroq ma’lumotlar ko‘liga hech qachon yetib bormaganini tasdiqladik. Sequence number’larini taqqoslash yo‘qotishlar spike davrining ma’lum bir nuqtasidan keyin to‘planganini ko‘rsatdi.
Xabarlar relay segmentlari qayta ishlay oladigan tezlikda oqib kelish o‘rniga nega birdaniga kelganini aniqlash uchun qayta uzatish logikasini tekshirdik va u rate control’siz barcha saqlangan xabarlarni sikl ichida ketma-ket darhol publish qilayotganini aniqladik. Bundan ham muammolisi shundaki, muvaffaqiyatsiz xabarlar darhol qayta urinilgan va shu tariqa allaqachon to‘yingan relay segmentlariga retry trafigi qo‘shilib, vaziyatni yanada yomonlashtirgan.
Oxir-oqibat, aloqa tiklanganda to‘planib qolgan xabarlar TPS limitidan bir necha baravar yuqori tezlikda oqib kelib, relay segmentlarini to‘ldirib yubordi. Throttling sababli yuzaga kelgan kechikishlar darhol amalga oshirilgan retry’lar bilan qo‘shilib, backlog’ning qor uyumidek kattalashishiga va oxir-oqibat ayrim xabarlarning yo‘qolishiga olib keldi.
Yaxshiyamki, buni Spike Test orqali aniqlay oldik. Xabarlar TPS limitidan past bo‘lgan bir xil tezlikda oqishi uchun qayta uzatish segmentiga token-bucket asosidagi rate limiting qo‘shdik va muvaffaqiyatsizlik yuz berganda retry xatti-harakatini exponential backoff’dan foydalanadigan qilib o‘zgartirdik. Bu to‘satdan yuzaga keladigan trafik keskinligi relay segmentlarini ishdan chiqarishining oldini oldi. Yaxshilanishlardan so‘ng xuddi shu ssenariyni yana ishga tushirganimizda, barcha xabarlar yo‘qotishlarsiz ma’lumotlar ko‘liga yuklandi va spike’dan keyin backlog’ni bo‘shatish uchun zarur vaqt oldindan aytish mumkin bo‘lgan oraliqda bo‘ldi.
Xulosa
Spike Test “Bu tizim qanchalik tez?” degan savolni emas, balki “U kutilmagan lahzalarga qanday bardosh beradi va normal holatga qanchalik tez qaytadi?” degan savolni tekshirish vositasidir. Faqat o‘rtacha trafik asosida loyihalashtirilgan tizimlar odatda normal sharoitda muammosiz ishlaydi. Shu sababli to‘satdan yuzaga keladigan keskin oqimlar ochib beradigan zaifliklar production’da hodisaga sabab bo‘lmaguncha kamdan-kam ko‘rinadi.
Agar tizimda qayta uzatish yoki retry kabi burst’larni tabiiy ravishda yuzaga keltiradigan logika mavjud bo‘lsa va uning oldida TPS bilan cheklangan segment tursa, funksional tekshiruv yakunlangandan keyin kamida bir marta Spike Test o‘tkazish foydali.
jungboke