Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Jarayoni soddalashtirilgan va o'nlab bir-biriga bog'langan xizmatlarga ega Lamoda kabi yirik kompaniyani o'z yondashuvini sezilarli darajada o'zgartirishga nima majbur qilishi mumkin? Motivatsiya butunlay boshqacha bo'lishi mumkin: qonunchilikdan tortib barcha dasturchilarga xos bo'lgan tajriba qilish istagigacha.

Ammo bu siz qo'shimcha imtiyozlarga umid qila olmaysiz degani emas. Sergey Zaika sizga Kafkada voqealarga asoslangan APIni qo'llasangiz, aniq nima yutib olishingiz mumkinligini aytib beradi (oz). Katta suratlar va qiziqarli kashfiyotlar haqida ham albatta gap bo'ladi - ularsiz tajriba o'tkazib bo'lmaydi.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Rad etish: Ushbu maqola Sergeyning 2018 yil noyabr oyida HighLoad++ da o'tkazgan uchrashuvi materiallariga asoslangan. Lamodaning Kafka bilan ishlash bo'yicha jonli tajribasi tinglovchilarni jadvaldagi boshqa hisobotlardan kam bo'lmagan holda o'ziga tortdi. O'ylaymizki, bu siz doimo hamfikr odamlarni topishingiz mumkinligi va kerakligining ajoyib namunasidir va HighLoad++ tashkilotchilari bunga qulay muhit yaratishga harakat qilishda davom etadilar.

Jarayon haqida

Lamoda o'zining aloqa markaziga, yetkazib berish xizmatiga (va ko'plab filiallarga), fotostudiyaga, ulkan omborga ega bo'lgan yirik elektron tijorat platformasi va bularning barchasi o'z dasturiy ta'minotida ishlaydi. O'nlab to'lov usullari mavjud, b2b hamkorlari ushbu xizmatlarning bir qismini yoki barchasini ishlatishi mumkin va o'z mahsulotlari haqida so'nggi ma'lumotlarni bilishni xohlaydi. Bundan tashqari, Lamoda Rossiya Federatsiyasidan tashqari uchta mamlakatda ishlaydi va u erda hamma narsa biroz boshqacha. Umuman olganda, yangi buyurtmani sozlashning yuzdan ortiq usullari mavjud bo'lib, ular o'z yo'lida qayta ishlanishi kerak. Bularning barchasi ba'zan noaniq usullar bilan aloqa qiladigan o'nlab xizmatlar yordamida ishlaydi. Bundan tashqari, asosiy mas'uliyat buyurtma holatlari bo'lgan markaziy tizim mavjud. Biz uni BOB deb ataymiz, men u bilan ishlayman.

Voqealarga asoslangan API bilan to'lovni qaytarish vositasi

Voqealar bilan bog'liq so'z juda noaniq; biroz keyinroq biz bu nimani anglatishini batafsilroq aniqlaymiz. Men Kafkada voqealarga asoslangan API yondashuvini sinab ko'rishga qaror qilgan kontekstdan boshlayman.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Har qanday do'konda xaridorlar to'laydigan buyurtmalarga qo'shimcha ravishda, mahsulot xaridorga mos kelmagani uchun do'kon pulni qaytarishni talab qiladigan holatlar mavjud. Bu nisbatan qisqa jarayon: agar kerak bo'lsa, biz ma'lumotlarni aniqlaymiz va pul o'tkazamiz.

Ammo qonunchilikdagi o'zgarishlar tufayli qaytarish yanada murakkablashdi va biz buning uchun alohida mikroservisni joriy qilishimiz kerak edi.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Bizning motivatsiyamiz:

  1. FZ-54 qonuni - qisqasi, qonun soliq idorasiga har bir pul muomalasi to'g'risida hisobot berishni talab qiladi, xoh u deklaratsiya yoki kvitansiya bo'lsin, bir necha daqiqadan iborat juda qisqa SLA ichida. Biz elektron tijorat kompaniyasi sifatida juda ko'p operatsiyalarni bajaramiz. Texnik jihatdan, bu yangi mas'uliyat (va shuning uchun yangi xizmat) va barcha jalb qilingan tizimlarni yaxshilashni anglatadi.
  2. BOB bo'linishi BOBni ko'p sonli asosiy bo'lmagan mas'uliyatdan ozod qilish va uning umumiy murakkabligini kamaytirish bo'yicha kompaniyaning ichki loyihasidir.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Ushbu diagrammada asosiy Lamoda tizimlari ko'rsatilgan. Endi ularning aksariyati ko'proq qisqarib borayotgan monolit atrofida 5-10 mikroservislar turkumi. Ular asta-sekin o'sib bormoqda, lekin biz ularni kichikroq qilishga harakat qilmoqdamiz, chunki o'rtada tanlangan fragmentni joylashtirish qo'rqinchli - biz uning tushishiga yo'l qo'ymaymiz. Biz barcha almashinuvlarni (o'qlarni) zahiraga olishga majburmiz va ularning har biri mavjud bo'lmasligi mumkinligini hisobga olamiz.

BOB-da juda ko'p birjalar mavjud: to'lov tizimlari, etkazib berish tizimlari, xabarnomalar tizimlari va boshqalar.

Texnik jihatdan BOB:

  • ~150k qator kod + ~100k qator testlar;
  • php7.2 + Zend 1 va Symfony komponentlari 3;
  • >100 API va ~50 chiquvchi integratsiya;
  • O'z biznes mantig'iga ega 4 mamlakat.

BOBni o'rnatish qimmat va og'riqli, u hal qiladigan kodlar va muammolar shunchalik ko'pki, hech kim hammasini boshiga solib qo'ya olmaydi. Umuman olganda, uni soddalashtirish uchun juda ko'p sabablar mavjud.

Qaytish jarayoni

Dastlab, jarayonda ikkita tizim ishtirok etadi: BOB va To'lov. Endi yana ikkitasi paydo bo'ladi:

  • Fiskalizatsiya xizmati, fiskalizatsiya va tashqi xizmatlar bilan bog'lanish bilan bog'liq muammolarni hal qiladi.
  • BOBni oshirib yubormaslik uchun yangi almashinuvlarni o'z ichiga olgan to'lovni qaytarish vositasi.

Endi jarayon quyidagicha ko'rinadi:

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

  1. BOB pulni qaytarish so'rovini oladi.
  2. BOB ushbu to'lovni qaytarish vositasi haqida gapiradi.
  3. To'lovni qaytarish vositasi to'lovga: "Pulni qaytaring" deb aytadi.
  4. To'lov pulni qaytaradi.
  5. Pulni qaytarish vositasi va BOB statuslarni bir-biri bilan sinxronlashtiradi, chunki hozircha ikkalasiga ham kerak. Toʻlovni qaytarish vositasiga hali toʻliq oʻtishga tayyor emasmiz, chunki BOBda UI, buxgalteriya hisobi uchun hisobotlar va umuman osonlikcha uzatib boʻlmaydigan koʻplab maʼlumotlar mavjud. Siz ikkita stulga o'tirishingiz kerak.
  6. Fiskalizatsiya talabi yo'qoladi.

Natijada biz Kafkada o'ziga xos voqea avtobusini - voqea-avtobusni yaratdik, unda hamma narsa boshlandi. Huray, endi bizda bitta muvaffaqiyatsizlik nuqtasi bor (sarkazm).

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Ijobiy va salbiy tomonlari juda aniq. Biz avtobus yasadik, demak, endi barcha xizmatlar unga bog'liq. Bu dizaynni soddalashtiradi, lekin tizimga bitta nosozlik nuqtasini kiritadi. Kafka qulab tushadi, jarayon to'xtaydi.

Voqealarga asoslangan API nima

Bu savolga yaxshi javob Martin Faulerning hisobotida (GOTO 2017) "Hodisaga asoslangan arxitekturaning ko'p ma'nolari".

Biz nima qildik qisqacha:

  1. orqali barcha asinxron almashinuvlarni o'rash voqealarni saqlash. Har bir qiziqqan iste'molchini tarmoq orqali status o'zgarishi haqida xabardor qilish o'rniga, biz markazlashtirilgan xotiraga holat o'zgarishi haqida voqea yozamiz va mavzuga qiziqqan iste'molchilar u erda paydo bo'lgan hamma narsani o'qiydilar.
  2. Bu holda voqea xabarnoma (xabarnomalar) biror joyda biror narsa o'zgargan. Masalan, buyurtma holati o'zgargan. Xabarnomaga kiritilmagan holat o'zgarishi bilan bog'liq ba'zi ma'lumotlarga qiziqqan iste'molchi uning holatini o'zi bilishi mumkin.
  3. Maksimal variant - to'liq huquqli voqea manbalari, davlat o'tkazmasi, qaysi voqea qayta ishlash uchun zarur bo'lgan barcha ma'lumotlarni o'z ichiga oladi: u qayerdan kelgan va qanday maqomga o'tgan, ma'lumotlar aniq qanday o'zgargan va hokazo. Yagona savol - siz saqlashga qodir bo'lgan ma'lumotlarning texnik imkoniyatlari va miqdori.

Pulni qaytarish vositasini ishga tushirish doirasida biz uchinchi variantdan foydalandik. Ushbu hodisani qayta ishlash soddalashtirilgan, chunki batafsil ma'lumot olishning hojati yo'q edi, shuningdek, har bir yangi voqea iste'molchilardan aniqlik kiritish so'rovlarini keltirib chiqaradigan stsenariyni yo'q qildi.

To'lovni qaytarish vositasi xizmati yuklanmagan, shuning uchun Kafkada zaruratdan ko'ra qalamning ta'mi ko'proq. Agar pulni qaytarish xizmati yuqori yuklangan loyihaga aylansa, biznes baxtli bo'ladi deb o'ylamayman.

Asinxron almashinuvi

Asinxron almashinuvlar uchun PHP bo'limi odatda RabbitMQ dan foydalanadi. Biz so'rov uchun ma'lumotlarni to'pladik, uni navbatga qo'ydik va xuddi shu xizmatning iste'molchisi uni o'qib chiqdi va yubordi (yoki yubormadi). API-ning o'zi uchun Lamoda Swagger-dan faol foydalanadi. Biz API-ni loyihalashtiramiz, uni Swagger-da tasvirlaymiz va mijoz va server kodini yaratamiz. Biz, shuningdek, biroz yaxshilangan JSON RPC 2.0 dan foydalanamiz.

Ba'zi joylarda ESB avtobuslari ishlatiladi, ba'zilari activeMQ-da yashaydi, lekin, umuman olganda, RabbitMQ - standart.

Async almashinuvi TO BE

Voqealar avtobusi orqali almashinuvni loyihalashda o'xshashlikni kuzatish mumkin. Hodisa tuzilmasi tavsiflari orqali kelajakdagi ma'lumotlar almashinuvini xuddi shunday tasvirlaymiz. Yaml formati, biz kod ishlab chiqarishni o'zimiz qilishimiz kerak edi, generator spetsifikatsiyaga muvofiq DTO'larni yaratadi va mijozlar va serverlarni ular bilan ishlashni o'rgatadi. Avlod ikki tilga o'tadi - golang va php. Bu kutubxonalarni izchil saqlashga yordam beradi. Generator golang tilida yozilgan, shuning uchun u gogi nomini oldi.

Kafkadagi voqealar manbasi odatiy holdir. Kafka Confluent ning asosiy korporativ versiyasidan yechim bor nakadi, domen birodarlarimiz Zalandodan yechim. Bizning vanil Kafka bilan boshlash uchun motivatsiya - bu biz uni hamma joyda ishlatish-qilmaslik to'g'risida qaror qabul qilmagunimizcha, shuningdek, o'zimizga manevr va takomillashtirish uchun joy qoldirmagunimizcha, yechimni bepul qoldirishni anglatadi: biz o'zimizni qo'llab-quvvatlashni xohlaymiz. JSON RPC 2.0, ikkita til uchun generatorlar va yana nima ekanligini ko'rib chiqaylik.

Ajablanarlisi shundaki, hatto shunday baxtli holatda ham, taxminan shunga o'xshash biznes mavjud bo'lsa, Zalando, taxminan o'xshash echimni ishlab chiqdi, biz undan samarali foydalana olmaymiz.

Ishga tushirish paytida arxitektura naqshlari quyidagicha: biz to'g'ridan-to'g'ri Kafkadan o'qiymiz, lekin faqat voqealar avtobusi orqali yozamiz. Kafkada o'qish uchun juda ko'p narsa bor: brokerlar, balanschilar va u gorizontal o'lchovga ko'proq yoki kamroq tayyor, men buni saqlamoqchi edim. Biz yozuvni bitta Gateway aka Events-avtobus orqali yakunlamoqchi edik va buning sababi.

Voqealar - avtobus

Yoki tadbir avtobusi. Bu oddiygina fuqaroligi bo'lmagan http shlyuz bo'lib, u bir nechta muhim rollarni bajaradi:

  • Tasdiqlash ishlab chiqarish — tadbirlar bizning talablarimizga mos kelishini tekshiramiz.
  • Voqealar ustasi tizimi, ya'ni bu kompaniyadagi asosiy va yagona tizim bo'lib, qaysi hodisalar bilan qaysi tuzilmalar haqiqiy deb hisoblanadigan savolga javob beradi. Tasdiqlash shunchaki tarkibni aniq belgilash uchun ma'lumotlar turlari va raqamlarini o'z ichiga oladi.
  • Xesh funktsiyasi sharding uchun - Kafka xabar strukturasi kalit-qiymatdir va kalit xesh yordamida uni qaerga qo'yish kerakligi hisoblab chiqiladi.

Nima uchun

Biz soddalashtirilgan jarayonga ega yirik kompaniyada ishlaymiz. Nima uchun biror narsani o'zgartirish kerak? Bu tajriba, va biz bir nechta foyda olishni kutmoqdamiz.

1:n+1 almashinuvi (birdan ko'pga)

Kafka yangi iste'molchilarni APIga ulashni juda oson qiladi.

Aytaylik, sizda bir vaqtning o'zida bir nechta tizimlarda (va ba'zi yangilarida) yangilanib turishingiz kerak bo'lgan katalogingiz bor. Ilgari biz set-API-ni amalga oshiradigan to'plamni ixtiro qildik va asosiy tizim iste'molchi manzillari haqida ma'lumot oldi. Endi asosiy tizim mavzu bo'yicha yangilanishlarni yuboradi va uni qiziqtirgan har bir kishi o'qiydi. Yangi tizim paydo bo'ldi - biz uni mavzuga yozdik. Ha, shuningdek, to'plam, lekin oddiyroq.

BOBning bir qismi bo'lgan qaytarib berish vositasi bo'lsa, ularni Kafka orqali sinxronlashtirish biz uchun qulaydir. To'lovda aytilishicha, pul qaytarilgan: BOB, RT bundan xabar topdi, maqomlarini o'zgartirdi, Fiskalizatsiya xizmati bu haqda bilib, chek berdi.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Biz mijozni uning buyurtmasi/qaytarilishi haqidagi yangiliklardan xabardor qiladigan yagona bildirishnomalar xizmatini yaratishni rejalashtirmoqdamiz. Endi bu mas'uliyat tizimlar o'rtasida taqsimlanadi. Bildirishnomalar xizmatiga Kafkadan tegishli ma'lumotlarni olish va unga javob berishni o'rgatishimiz kifoya qiladi (va boshqa tizimlarda bu bildirishnomalarni o'chirib qo'yish). Yangi to'g'ridan-to'g'ri almashinuvlar talab qilinmaydi.

Ma'lumotlarga asoslangan

Tizimlar orasidagi ma'lumotlar shaffof bo'ladi - sizda qanday "qonli korxona" bo'lishidan qat'i nazar va sizning orqangiz qanchalik to'la bo'lishidan qat'i nazar. Lamoda'da tizimlardan ma'lumotlarni to'playdigan va ularni biznes uchun ham, aqlli tizimlar uchun ham qayta foydalanish mumkin bo'lgan shaklga qo'yadigan Data Analytics bo'limi mavjud. Kafka sizga tezda ularga juda ko'p ma'lumotlarni berish va bu ma'lumotlar oqimini yangilab turish imkonini beradi.

Replikatsiya jurnali

Xabarlar RabbitMQ da bo'lgani kabi o'qilgandan keyin ham yo'qolmaydi. Voqea qayta ishlash uchun etarli ma'lumotni o'z ichiga olgan bo'lsa, bizda ob'ektdagi so'nggi o'zgarishlar tarixi va agar xohlasangiz, ushbu o'zgarishlarni qo'llash imkoniyati mavjud.

Replikatsiya jurnalining saqlash muddati ushbu mavzuga yozish intensivligiga bog'liq; Kafka sizga saqlash vaqti va ma'lumotlar hajmi bo'yicha cheklovlarni moslashuvchan tarzda o'rnatish imkonini beradi. Intensiv mavzular uchun barcha iste'molchilar ma'lumot yo'qolishidan oldin, hatto qisqa muddatli ishlamay qolgan taqdirda ham o'qishga vaqtlari bo'lishi muhimdir. Odatda ma'lumotlarni saqlash mumkin kun birliklari, bu qo'llab-quvvatlash uchun etarli.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Keyin, Kafka bilan tanish bo'lmaganlar uchun hujjatlar haqida bir oz qayta hikoya qilish (rasm ham hujjatlardan olingan)

AMQP navbatlarga ega: biz iste'molchi uchun navbatga xabarlar yozamiz. Odatda, bitta navbat bir xil biznes mantig'iga ega bo'lgan bitta tizim tomonidan qayta ishlanadi. Agar siz bir nechta tizimlarni xabardor qilishingiz kerak bo'lsa, siz dasturni bir nechta navbatga yozishni o'rgatishingiz yoki ularni o'zi klonlaydigan fanout mexanizmi bilan almashinuvni sozlashingiz mumkin.

Kafka ham xuddi shunday abstraksiyaga ega mavzu, unda siz xabarlar yozasiz, lekin ular o'qigandan keyin yo'qolmaydi. Odatiy bo'lib, Kafkaga ulanganingizda, siz barcha xabarlarni olasiz va to'xtagan joyingizda saqlash imkoniyati mavjud. Ya'ni, siz ketma-ket o'qiysiz, siz xabarni o'qilgan deb belgilamasligingiz mumkin, lekin keyin o'qishni davom ettirishingiz mumkin bo'lgan identifikatorni saqlang. Siz o'rnatgan identifikator ofset deb ataladi va mexanizm offset deb ataladi.

Shunga ko'ra, turli xil mantiqni amalga oshirish mumkin. Misol uchun, bizda turli mamlakatlar uchun 4 ta holatda BOB mavjud - Lamoda Rossiya, Qozog'iston, Ukraina, Belorussiyada. Ular alohida joylashtirilganligi sababli, ular biroz boshqacha konfiguratsiyaga va o'zlarining biznes mantiqlariga ega. Biz xabarda qaysi davlatga tegishli ekanligini ko'rsatamiz. Har bir mamlakatdagi har bir BOB iste'molchisi boshqa groupId bilan o'qiydi va agar xabar ularga tegishli bo'lmasa, uni o'tkazib yuboradi, ya'ni. darhol +1 ofsetini amalga oshiradi. Agar xuddi shu mavzu bizning To'lov xizmatimiz tomonidan o'qilsa, u buni alohida guruh bilan bajaradi va shuning uchun ofsetlar kesishmaydi.

Tadbir talablari:

  • Ma'lumotlarning to'liqligi. Men voqeani qayta ishlash uchun etarli ma'lumotlarga ega bo'lishini xohlayman.

  • Butunlik Biz Voqealar-avtobusga voqea izchilligini va uni qayta ishlashi mumkinligini tekshirishni topshiramiz.
  • Buyurtma muhim. Qaytgan taqdirda biz tarix bilan ishlashga majburmiz. Bildirishnomalar bilan buyurtma muhim emas, agar ular bir xil bildirishnomalar bo'lsa, qaysi buyurtma birinchi bo'lib kelganidan qat'i nazar, elektron pochta bir xil bo'ladi. To'lovni qaytarishda aniq jarayon mavjud; agar buyurtmani o'zgartirsak, istisnolar paydo bo'ladi, to'lov yaratilmaydi yoki qayta ishlanmaydi - biz boshqa maqomga ega bo'lamiz.
  • Muvofiqlik. Bizning do'konimiz bor va endi biz API o'rniga voqealar yaratamiz. Bizga xizmatlarimizga yangi voqealar va mavjudlariga kiritilgan o'zgarishlar haqidagi ma'lumotlarni tez va arzon tarzda uzatish usuli kerak. Bunga alohida git ombori va kod generatorlaridagi umumiy spetsifikatsiya orqali erishiladi. Shuning uchun turli xizmatlardagi mijozlar va serverlar muvofiqlashtiriladi.

Lamodadagi Kafka

Bizda uchta Kafka o'rnatish mavjud:

  1. Jurnallar;
  2. R&D;
  3. Voqealar - avtobus.

Bugun biz faqat oxirgi nuqta haqida gapiramiz. Voqealar-avtobusda bizda juda katta o'rnatishlar mavjud emas - 3 ta broker (server) va atigi 27 ta mavzu. Qoida tariqasida, bitta mavzu bitta jarayondir. Ammo bu nozik nuqta va biz hozir unga to'xtalib o'tamiz.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Yuqorida rps grafigi. To'lovlarni qaytarish jarayoni firuza chiziq bilan belgilangan (ha, X o'qida), pushti chiziq esa kontentni yangilash jarayonidir.

Lamoda katalogi millionlab mahsulotlarni o'z ichiga oladi va ma'lumotlar doimo yangilanadi. Ba'zi to'plamlar modadan chiqib ketadi, ularning o'rniga yangilari chiqariladi va katalogda doimiy ravishda yangi modellar paydo bo'ladi. Biz ertaga mijozlarimizga nima qiziqarli bo'lishini oldindan aytishga harakat qilamiz, shuning uchun biz doimo yangi narsalarni sotib olamiz, ularni suratga olamiz va vitrinani yangilaymiz.

Pushti cho'qqilar - mahsulot yangilanishlari, ya'ni mahsulotlardagi o'zgarishlar. Ko'rinib turibdiki, yigitlar suratga tushishdi, suratga olishdi va keyin yana! - tadbirlar to'plami yuklangan.

Lamoda Events foydalanish holatlari

Biz quyidagi operatsiyalar uchun qurilgan arxitekturadan foydalanamiz:

  • Qaytish holatini kuzatish: harakatga chaqirish va barcha jalb qilingan tizimlardan holatni kuzatish. To'lov, holatlar, fiskalizatsiya, bildirishnomalar. Bu erda biz yondashuvni sinab ko'rdik, asboblar yaratdik, barcha xatolarni to'pladik, hujjatlarni yozdik va hamkasblarimizga undan qanday foydalanishni aytdik.
  • Mahsulot kartalarini yangilash: konfiguratsiya, meta-ma'lumotlar, xarakteristikalar. Bitta tizim o'qiydi (ko'rsatadi) va bir nechta yozadi.
  • Elektron pochta, push va sms: buyurtma yig'ildi, buyurtma keldi, qaytarish qabul qilindi va hokazo, ular juda ko'p.
  • Zaxira, omborni yangilash — buyumlarning miqdoriy yangilanishi, shunchaki raqamlar: omborga kelish, qaytish. Tovarlarni bron qilish bilan bog'liq barcha tizimlar eng dolzarb ma'lumotlar bilan ishlashi kerak. Hozirgi vaqtda aktsiyalarni yangilash tizimi juda murakkab; Kafka uni soddalashtiradi.
  • Ma'lumotlarni tahlil qilish (Ar-ge bo'limi), ML vositalari, tahlillar, statistika. Biz ma'lumot shaffof bo'lishini xohlaymiz - Kafka bunga juda mos keladi.

Endi so'nggi olti oy ichida sodir bo'lgan katta zarbalar va qiziqarli kashfiyotlar haqida qiziqarli qism.

Dizayn muammolari

Aytaylik, biz yangi ish qilmoqchimiz - masalan, butun etkazib berish jarayonini Kafkaga o'tkazing. Endi jarayonning bir qismi BOBda Buyurtmalarni qayta ishlashda amalga oshirilmoqda. Buyurtmani yetkazib berish xizmatiga o'tkazish, oraliq omborga ko'chirish va hokazolarning orqasida status modeli mavjud. To'liq monolit, hatto ikkitasi va etkazib berishga bag'ishlangan bir nechta API mavjud. Ular etkazib berish haqida ko'proq bilishadi.

Bular o'xshash sohalar kabi ko'rinadi, ammo BOBdagi Buyurtmani qayta ishlash va Yuk tashish tizimi turli maqomlarga ega. Misol uchun, ba'zi kurerlik xizmatlari oraliq statuslarni yubormaydi, faqat oxirgi: "etkazib berildi" yoki "yo'qolgan". Boshqalar, aksincha, tovarlar harakati haqida batafsil ma'lumot berishadi. Har kimning o'z tasdiqlash qoidalari bor: ba'zilar uchun elektron pochta haqiqiy, ya'ni u qayta ishlanadi; boshqalar uchun bu haqiqiy emas, lekin buyurtma hali ham qayta ishlanadi, chunki aloqa uchun telefon raqami mavjud va kimdir bunday buyurtma umuman ko'rib chiqilmaydi, deb aytadi.

Ma'lumotlar oqimi

Kafka misolida ma'lumotlar oqimini tashkil qilish masalasi tug'iladi. Bu vazifa bir nechta fikrlarga asoslangan strategiyani tanlashni o'z ichiga oladi; keling, ularning barchasini ko'rib chiqaylik.

Bitta mavzudami yoki turli mavzulardami?

Bizda tadbir spetsifikatsiyasi mavjud. BOBda biz falon buyurtmani etkazib berish kerakligini yozamiz va quyidagilarni ko'rsatamiz: buyurtma raqami, uning tarkibi, ba'zi SKU va shtrix kodlari va boshqalar. Tovarlar omborga kelganida, etkazib berish statuslar, vaqt belgilari va barcha kerakli narsalarni olishi mumkin. Ammo keyin biz BOBda ushbu ma'lumotlar bo'yicha yangilanishlarni olishni xohlaymiz. Bizda yetkazib berishdan ma'lumotlarni olishning teskari jarayoni mavjud. Bu xuddi shunday voqeami? Yoki bu o'z mavzusiga loyiq bo'lgan alohida almashinuvmi?

Ehtimol, ular juda o'xshash bo'ladi va bitta mavzuni yaratish vasvasasi asossiz emas, chunki alohida mavzu alohida iste'molchilarni, alohida konfiguratsiyalarni, bularning barchasini alohida avlodni anglatadi. Lekin fakt emas.

Yangi maydonmi yoki yangi voqeami?

Ammo agar siz xuddi shu hodisalardan foydalansangiz, unda boshqa muammo paydo bo'ladi. Misol uchun, barcha etkazib berish tizimlari BOB yaratishi mumkin bo'lgan DTO turini yarata olmaydi. Biz ularga identifikatorni yuboramiz, lekin ular uni saqlashmaydi, chunki ularga kerak emas va voqea-avtobus jarayonini boshlash nuqtai nazaridan, bu maydon talab qilinadi.

Agar biz voqea-avtobus uchun ushbu maydon kerak bo'lgan qoidani kiritsak, biz BOBda yoki start hodisasi ishlov beruvchisida qo'shimcha tekshirish qoidalarini o'rnatishga majbur bo'lamiz. Tasdiqlash butun xizmat bo'ylab tarqala boshlaydi - bu juda qulay emas.

Yana bir muammo - bosqichma-bosqich rivojlanish vasvasasi. Bizga voqeaga nimadir qo'shish kerak, deb aytishadi, balki, o'ylab ko'rsak, bu alohida voqea bo'lishi kerak edi. Ammo bizning sxemamizda alohida hodisa alohida mavzudir. Alohida mavzu men yuqorida tasvirlab bergan butun jarayondir. Ishlab chiquvchi JSON sxemasiga boshqa maydon qo'shish va uni qayta tiklash vasvasasiga tushadi.

To'lovlarni qaytarish bo'lsa, biz yarim yil ichida sodir bo'lgan voqeaga etib keldik. Bizda pulni qaytarish yangilanishi deb nomlangan bitta meta-hodisaga ega bo'ldik, unda ushbu yangilanish aslida nima ekanligini tavsiflovchi turdagi maydon mavjud edi. Shu sababli, bizda validatorlar bilan "ajoyib" kalitlar bor edi, ular bizga ushbu hodisani ushbu turdagi bilan qanday tekshirishni aytdilar.

Hodisa versiyasi

Kafkadagi xabarlarni tekshirish uchun siz foydalanishingiz mumkin Evro, lekin darhol unga yotish va Confluent-dan foydalanish kerak edi. Bizning holatlarimizda versiyalar bilan ehtiyot bo'lishimiz kerak. Replikatsiya jurnalidan xabarlarni qayta o'qish har doim ham mumkin bo'lmaydi, chunki modelda "chap" bor. Asosan, model orqaga qarab mos bo'lishi uchun versiyalar yaratiladi: masalan, maydonni vaqtincha ixtiyoriy qiling. Agar farqlar juda kuchli bo'lsa, biz yangi mavzuda yozishni boshlaymiz va mijozlarni eskisini o'qib bo'lgach, o'tkazamiz.

Bo'limlarning kafolatlangan o'qish tartibi

Kafka ichidagi mavzular bo'limlarga bo'lingan. Biz sub'ektlar va birjalarni loyihalashda bu unchalik muhim emas, lekin uni qanday iste'mol qilish va kengaytirishni hal qilishda muhim ahamiyatga ega.

Odatdagidek, Kafkada bitta mavzu yozasiz. Odatiy bo'lib, bitta bo'lim ishlatiladi va ushbu mavzudagi barcha xabarlar unga o'tadi. Iste'molchi esa bu xabarlarni ketma-ket o'qiydi. Aytaylik, endi xabarlarni ikki xil iste'molchi o'qishi uchun tizimni kengaytirishimiz kerak. Agar siz, masalan, SMS yuborayotgan bo'lsangiz, Kafkaga qo'shimcha bo'lim qilishni aytishingiz mumkin va Kafka xabarlarni ikki qismga bo'lishni boshlaydi - yarmi bu erda, yarmi bu erda.

Kafka ularni qanday ajratadi? Har bir xabarning tanasi (biz JSON saqlanuvchi) va kalit mavjud. Siz ushbu kalitga xash funksiyasini qo'shishingiz mumkin, bu xabar qaysi bo'limga kirishini aniqlaydi.

To'lovlarni qaytarish bilan bog'liq holda, bu juda muhim, agar biz ikkita bo'limni olsak, parallel iste'molchi ikkinchi voqeani birinchisidan oldin qayta ishlashi va muammo yuzaga kelishi ehtimoli bor. Xesh funktsiyasi bir xil kalitga ega bo'lgan xabarlar bir xil bo'limda tugashini ta'minlaydi.

Voqealar va buyruqlar

Bu biz duch kelgan yana bir muammo. Voqea - bu ma'lum bir voqea: biz biror joyda biror narsa sodir bo'lganligini aytamiz (bir narsa_bo'ldi), masalan, ob'ekt bekor qilindi yoki pul qaytarildi. Agar kimdir ushbu voqealarni tinglasa, "element bekor qilindi" ga ko'ra, to'lovni qaytarish sub'ekti yaratiladi va sozlamalarning biron bir joyida "to'lov amalga oshirildi" deb yoziladi.

Ammo, odatda, voqealarni loyihalashda siz ularni behuda yozishni xohlamaysiz - kimdir ularni o'qib chiqishiga ishonasiz. Nimadir_bo'ldi (buyum bekor qilindi, to'lov qaytarildi) emas, balki nimadir_bajarilishi kerak deb yozishga vasvasa bor. Masalan, buyum qaytarib berishga tayyor.

Bir tomondan, bu voqea qanday ishlatilishini taklif qiladi. Boshqa tomondan, bu oddiy hodisa nomiga o'xshamaydi. Bundan tashqari, bu yerdan do_something buyrug'i uzoq emas. Lekin kimdir bu voqeani o'qiganiga hech qanday kafolatingiz yo'q; va agar siz uni o'qisangiz, uni muvaffaqiyatli o'qiysiz; va agar siz uni muvaffaqiyatli o'qisangiz, unda siz nimadir qildingiz va bu narsa muvaffaqiyatli bo'ldi. Voqea biror narsaga aylanganda, fikr-mulohaza zarur bo'ladi va bu muammo.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

RabbitMQ-da asinxron almashinuvda siz xabarni o'qiganingizda, http-ga o'ting, sizda javob bor - hech bo'lmaganda xabar olingan. Kafkaga yozganingizda, Kafkaga yozgan xabaringiz bor, lekin u qanday qayta ishlangani haqida hech narsa bilmaysiz.

Shuning uchun, bizning holatlarimizda, agar shuncha ko'p voqealar yuborilgan bo'lsa, falon vaqtdan keyin bir xil miqdordagi javob hodisalari kelishi uchun javob berish hodisasini joriy qilish va monitoringni o'rnatish kerak edi. Agar bu sodir bo'lmasa, unda biror narsa noto'g'ri ketganga o'xshaydi. Misol uchun, agar biz "element_ready_to_refund" hodisasini yuborgan bo'lsak, biz pulni qaytarish yaratilishini, pul mijozga qaytarilishini va "pul_qaytarilgan" hodisasi bizga yuborilishini kutamiz. Ammo bu aniq emas, shuning uchun monitoring zarur.

Nayranglar

Juda aniq muammo bor: agar siz mavzuni ketma-ket o'qisangiz va sizda yomon xabar bo'lsa, iste'molchi tushadi va siz oldinga bormaysiz. Senga kerak barcha iste'molchilarni to'xtating, o'qishni davom ettirish uchun qo'shimcha ofsetni bajaring.

Biz bu haqda bilardik, hisobladik, lekin shunday bo'ldi. Va bu sodir bo'ldi, chunki voqea voqealar-avtobus nuqtai nazaridan, voqea dastur validatori nuqtai nazaridan haqiqiy edi, lekin PostgreSQL nuqtai nazaridan haqiqiy emas edi, chunki bizning tizimimizda MySQL UNSIGNED INT bilan tizimda faqat INT bilan PostgreSQL mavjud edi. Uning o'lchami biroz kichikroq va Id mos kelmadi. Simfoniya bundan mustasno vafot etdi. Biz, albatta, istisnoni ushladik, chunki biz unga tayandik va bu ofsetni amalga oshirmoqchi edik, lekin bundan oldin biz muammo hisoblagichini oshirmoqchi edik, chunki xabar muvaffaqiyatsiz bajarildi. Ushbu loyihadagi hisoblagichlar ham ma'lumotlar bazasida va Symfony allaqachon ma'lumotlar bazasi bilan aloqani yopgan va ikkinchi istisno butun jarayonni ofset qilish imkoniyatisiz o'ldiradi.

Xizmat bir muncha vaqt yotdi - xayriyatki, Kafka bilan bu unchalik yomon emas, chunki xabarlar qoladi. Ish tiklanganda, ularni o'qishni tugatishingiz mumkin. Bu qulay.

Kafka asboblar yordamida ixtiyoriy ofsetni o'rnatish qobiliyatiga ega. Lekin buning uchun siz barcha iste'molchilarni to'xtatib qo'yishingiz kerak - bizning holatlarimizda iste'molchilar, qayta joylashtirishlar bo'lmaydigan alohida nashr tayyorlang. Keyin Kafkada siz ofsetni asboblar orqali almashtirishingiz mumkin va xabar o'tadi.

Yana bir nuance - replikatsiya jurnali va rdkafka.so - loyihamizning o'ziga xos xususiyatlari bilan bog'liq. Biz PHP dan foydalanamiz va PHPda, qoida tariqasida, barcha kutubxonalar Kafka bilan rdkafka.so ombori orqali bog‘lanadi, keyin esa qandaydir o‘ram mavjud. Ehtimol, bu bizning shaxsiy qiyinchiliklarimizdir, lekin biz allaqachon o'qigan narsamizning bir qismini qayta o'qish unchalik oson emasligi ma'lum bo'ldi. Umuman olganda, dasturiy ta'minot bilan bog'liq muammolar mavjud edi.

Bo'limlar bilan ishlashning o'ziga xos xususiyatlariga qaytsak, u to'g'ridan-to'g'ri hujjatlarda yozilgan iste'molchilar >= mavzu bo'limlari. Ammo men bu haqda men xohlaganimdan ancha keyinroq bilib oldim. Agar siz ikkita iste'molchiga ega bo'lishni istasangiz, sizga kamida ikkita bo'lim kerak bo'ladi. Ya'ni, agar sizda 20 ming xabar to'plangan bitta bo'lim bo'lsa va siz yangisini yaratgan bo'lsangiz, xabarlar soni tez orada tenglashtirilmaydi. Shuning uchun, ikkita parallel iste'molchiga ega bo'lish uchun siz bo'limlar bilan shug'ullanishingiz kerak.

Monitoring

O'ylaymanki, biz buni qanday nazorat qilsak, mavjud yondashuvda qanday muammolar borligi yanada aniqroq bo'ladi.

Misol uchun, biz ma'lumotlar bazasida qancha mahsulot so'nggi paytlarda o'z holatini o'zgartirganligini hisoblab chiqamiz va shunga ko'ra, ushbu o'zgarishlar asosida voqealar sodir bo'lishi kerak edi va biz ushbu raqamni monitoring tizimimizga yuboramiz. Keyin Kafkadan biz ikkinchi raqamni olamiz, aslida qancha voqealar qayd etilgan. Shubhasiz, bu ikki raqam orasidagi farq har doim nolga teng bo'lishi kerak.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Bundan tashqari, siz ishlab chiqaruvchining qanday ishlashini, voqealar-avtobus xabarlarini qabul qilganligini va iste'molchining qanday ishlashini kuzatishingiz kerak. Misol uchun, quyidagi jadvallarda pulni qaytarish vositasi yaxshi ishlamoqda, ammo BOBda ba'zi muammolar bor (ko'k cho'qqilar).

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Men allaqachon iste'molchilar guruhining kechikishi haqida aytib o'tdim. Taxminan aytganda, bu o'qilmagan xabarlar soni. Umuman olganda, bizning iste'molchilarimiz tez ishlaydi, shuning uchun kechikish odatda 0 ni tashkil qiladi, lekin ba'zida qisqa muddatli cho'qqisi bo'lishi mumkin. Kafka buni qutidan tashqarida qila oladi, lekin siz ma'lum bir intervalni belgilashingiz kerak.

Loyiha bor Burrowbu sizga Kafka haqida ko'proq ma'lumot beradi. U shunchaki iste'molchi guruhi API-dan foydalanib, ushbu guruh qanday ishlayotgani haqida ma'lumot beradi. "OK" va "Muvaffaqiyatsiz" ga qo'shimcha ravishda, ogohlantirish mavjud va siz iste'molchilaringiz ishlab chiqarish sur'atlariga bardosh bera olmasligini bilib olishingiz mumkin - ular yozilganlarni tekshirishga vaqtlari yo'q. Tizim juda aqlli va ulardan foydalanish oson.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

API javobi shunday ko'rinadi. Bu erda bob-live-fifa guruhi, refund.update.v1 bo'limi, holati OK, kechikish 0 - oxirgi yakuniy ofset bunday va shunga o'xshash.

Kafkada asinxron API bilan pulni qaytarish vositasi xizmatini ishlab chiqish tajribasi

Monitoring yangilangan_SLA (tiqilib qolgan) Men allaqachon aytib o'tganman. Masalan, mahsulot qaytarib berishga tayyor degan holatga o'zgardi. Biz Cron-ni o'rnatamiz, unda aytilishicha, agar 5 daqiqada bu ob'ekt qaytarilmasa (biz to'lov tizimlari orqali pulni juda tez qaytaramiz), unda nimadir noto'g'ri ketdi va bu, albatta, qo'llab-quvvatlash uchun. Shuning uchun, biz shunchaki bunday narsalarni o'qiydigan Cronni olamiz va agar ular 0 dan katta bo'lsa, u ogohlantirish yuboradi.

Xulosa qilib aytadigan bo'lsak, voqealardan foydalanish qachon qulaydir:

  • ma'lumotlar bir nechta tizimlarga kerak;
  • qayta ishlash natijasi muhim emas;
  • bir nechta voqealar yoki kichik voqealar mavjud.

Maqolada juda aniq mavzu - Kafkadagi asinxron API borga o'xshaydi, ammo shu munosabat bilan men bir vaqtning o'zida ko'p narsalarni tavsiya qilmoqchiman.
Birinchidan, keyingi Yuqori yuk ++ biz noyabrgacha kutishimiz kerak, aprel oyida Sankt-Peterburg versiyasi bo'ladi, iyun oyida esa Novosibirskda yuqori yuklar haqida gapiramiz.
Ikkinchidan, ma'ruza muallifi Sergey Zaika bizning bilimlarni boshqarish bo'yicha yangi konferentsiyamiz Dastur qo'mitasi a'zosi. KnowledgeConf. Konferentsiya bir kunlik, 26 aprel kuni bo'lib o'tadi, lekin uning dasturi juda qizg'in.
Va may oyida bo'ladi PHP Rossiya и RIT++ (DevOpsConf bilan birga) - siz o'zingizning mavzuingizni u erda taklif qilishingiz, tajribangiz haqida gapirishingiz va to'ldirilgan konuslaringiz haqida shikoyat qilishingiz mumkin.

Manba: www.habr.com

a Izoh qo'shish