![Search icon](https://hackernoon.imgix.net/search-new.png?w=19&h=19)
Ishonchli, yuqori darajada mavjud, kengaytiriladigan taqsimlangan tizimni yaratish muayyan texnikalar, tamoyillar va naqshlarga rioya qilishni talab qiladi. Bunday tizimlarni loyihalash ko'plab muammolarni hal qilishni o'z ichiga oladi. Eng keng tarqalgan va asosiy muammolar orasida ikki tomonlama yozish muammosi mavjud.
"Ikki tomonlama yozish muammosi" taqsimlangan tizimlarda, asosan, sinxron saqlanishi kerak bo'lgan bir nechta ma'lumotlar manbalari yoki ma'lumotlar bazalari bilan ishlashda yuzaga keladigan muammodir. Bu ma'lumotlarning nomuvofiqligi, nizolar yoki ishlashdagi qiyinchiliklar kabi muammolarni keltirib chiqarmasdan, ma'lumotlar o'zgarishlarining doimiy ravishda ma'lumotlar bazalari yoki keshlar kabi turli xil ma'lumotlar do'konlariga yozilishini ta'minlash qiyinligini anglatadi.
Har bir xizmat uchun mikroservislar arxitekturasi va namunaviy ma'lumotlar bazasi sizga mustaqil joylashtirish va masshtablash, izolyatsiya qilingan nosozliklar va rivojlanish tezligini oshirish kabi ko'plab afzalliklarni beradi. Biroq, operatsiyalar bir nechta mikroservislar o'rtasida o'zgarishlarni talab qiladi, bu sizni ushbu muammoni hal qilish uchun ishonchli yechim haqida o'ylashga majbur qiladi.
Keling, bizning domenimiz kredit arizalarini qabul qilishni, ularni baholashni va mijozlarga bildirishnomalarni yuborishni o'z ichiga olgan stsenariyni ko'rib chiqaylik.
Yagona javobgarlik printsipi, Konvey qonuni va domenga asoslangan dizayn yondashuvi ruhida, bir nechta voqealar bo'roni seanslaridan so'ng, butun domen aniq chegaralari, domen modellari va hamma joyda mavjud bo'lgan tilga ega bo'lgan, belgilangan cheklangan kontekstli uchta subdomenga bo'lingan.
Birinchisi, yangi kredit arizalarini qabul qilish va to'plash vazifasini bajaradi. Ikkinchi tizim ushbu arizalarni baholaydi va taqdim etilgan ma'lumotlar asosida qarorlar qabul qiladi. Ushbu baholash jarayoni, jumladan, KYC/KYB, firibgarlikka qarshi va kredit xavfini tekshirish ko'p vaqt talab qilishi mumkin, bu esa bir vaqtning o'zida minglab ilovalar bilan ishlash qobiliyatini talab qiladi. Shunday qilib, bu funksiya mustaqil masshtablash imkonini beruvchi o‘z ma’lumotlar bazasiga ega bo‘lgan maxsus mikroservisga berilgan.
Bundan tashqari, ushbu quyi tizimlar ikkita turli jamoalar tomonidan boshqariladi, ularning har biri o'z chiqarish davrlari, xizmat ko'rsatish darajasi bo'yicha kelishuvlar (SLA) va kengayish talablariga ega.
Nihoyat , mijozlarga ogohlantirishlar yuborish uchun ixtisoslashgan xabar berish xizmati mavjud.
Bu erda tizimning asosiy foydalanish holatining aniq tavsifi:
Bu bir qarashda juda oddiy va ibtidoiy tizim, ammo keling, Kreditga ariza berish xizmati kredit arizasini topshirish buyrug'ini qanday qayta ishlashiga to'xtalib o'tamiz.
Xizmatlarning o'zaro ta'siri uchun ikkita yondashuvni ko'rib chiqishimiz mumkin:
Avval mahalliy-majburiy-keyin-nashr qilish: Ushbu yondashuvda xizmat o'zining mahalliy ma'lumotlar bazasini yangilaydi (majburiyat qiladi) va keyin boshqa xizmatlarga voqea yoki xabarni nashr etadi.
Avval nashr eting-keyin-mahalliy topshiring: Aksincha, bu usul mahalliy ma'lumotlar bazasiga o'zgartirish kiritishdan oldin voqea yoki xabarni nashr qilishni o'z ichiga oladi.
Ikkala usulning ham kamchiliklari bor va ular taqsimlangan tizimlarda aloqa uchun qisman xavfsizdir.
Bu birinchi yondashuvni qo'llashning ketma-ketlik diagrammasi.
Ushbu stsenariyda, Kreditga ariza berish xizmati “Birinchi-mahalliy-majburiy-keyin-nashr et” yondashuvidan foydalanadi, bunda u avval tranzaksiyani amalga oshiradi va keyin boshqa tizimga bildirishnoma yuborishga harakat qiladi. Biroq, bu jarayon, masalan, tarmoq bilan bog'liq muammolar mavjud bo'lsa, baholash xizmati mavjud bo'lmasa yoki Kreditga ariza berish xizmati xotirada (OOM) xatolikka duch kelsa va ishlamay qolsa, muvaffaqiyatsizlikka uchraydi. Bunday hollarda, agar qo'shimcha chora-tadbirlar ko'rilmasa, yangi kredit arizasi haqida ogohlantirmasdan, xabar yo'qoladi.
Va ikkinchisi.
"Birinchi nashr qilish-keyin-mahalliy majburiyat" stsenariysida Kreditga ariza berish xizmati ko'proq jiddiy xavflarga duch keladi. U yangi ilova haqida Baholash xizmatini xabardor qilishi mumkin, lekin maʼlumotlar bazasi bilan bogʻliq muammolar, xotira xatolari yoki kod xatolari tufayli ushbu yangilanishni mahalliy sifatida saqlay olmaydi. Ushbu yondashuv ma'lumotlarda sezilarli nomuvofiqliklarga olib kelishi mumkin, bu esa Kreditni ko'rib chiqish xizmati kiruvchi arizalarni qanday ko'rib chiqishiga qarab jiddiy muammolarni keltirib chiqarishi mumkin.
Shuning uchun biz tashqi iste'molchilarga voqealarni nashr etishning mustahkam mexanizmini taklif qiladigan yechimni aniqlashimiz kerak. Biroq, potentsial echimlarni ko'rib chiqishdan oldin, biz tarqatilgan tizimlarda erishish mumkin bo'lgan xabarlarni etkazib berish kafolatlari turlarini aniqlab olishimiz kerak.
Biz erishishimiz mumkin bo'lgan to'rt turdagi kafolatlar mavjud.
Hech qanday kafolatlar yo'q
Xabarning manzilga yetkazilishiga kafolat yo'q. “Birinchi-mahalliy-majburiy-keyin-nashr et” yondashuvi aynan shu haqida. Iste'molchilar xabarlarni bir marta, bir necha marta yoki umuman qabul qilishlari mumkin.
Ko'pi bilan bir marta yetkazib berish
Ko'pi bilan bir marta yetkazib berish xabarning belgilangan manzilga ko'pi bilan 1 marta yetkazilishini bildiradi. “Avval-mahalliy-majburiy-keyin-nashr et” yondashuvi birinchi qiymatga ega boʻlgan urinishlarning qayta urinish siyosati bilan ham shu tarzda amalga oshirilishi mumkin.
Kamida bir marta yetkazib berish\Iste'molchilar har bir xabarni oladi va qayta ishlaydi, lekin bir xil xabarni bir necha marta olishi mumkin.
Aynan bir marta yetkazib berish\To'liq bir marta yetkazib berish iste'molchining xabarni bir marta samarali qabul qilishini bildiradi.
Texnik jihatdan, Kafka tranzaktsiyalari va ishlab chiqaruvchi va iste'molchining aniq idempotent amalga oshirilishi bilan erishish mumkin.
Ko'pgina hollarda, "kamida bir marta" yetkazib berish kafolatlari xabarlarning kamida bir marta yetkazilishini ta'minlash orqali ko'plab muammolarni hal qiladi, ammo iste'molchilar idempotent bo'lishi kerak. Biroq, tarmoqning muqarrar nosozliklarini hisobga olgan holda, ishlab chiqaruvchining kafolatlaridan qat'i nazar, takroriy xabarlarni qayta ishlashdan qochish uchun barcha iste'molchilar mantig'i idempotent bo'lishi kerak. Shuning uchun, bu talab kamchilik emas, balki haqiqatni aks ettiradi.
Ushbu muammoni hal qilishning ko'plab usullari mavjud, ularning afzalliklari va kamchiliklari mavjud.
Vikipediyaga ko'ra, Ikki bosqichli majburiyat (2PC) - bu taqsimlangan tranzaktsiyalarning izchilligi va ishonchliligini ta'minlash uchun informatika va ma'lumotlar bazasini boshqarish tizimlarida qo'llaniladigan taqsimlangan tranzaksiya protokoli. U bir nechta resurslar (masalan, ma'lumotlar bazalari) bitta tranzaksiyada ishtirok etishi kerak bo'lgan holatlar uchun mo'ljallangan va ularning hammasi tranzaktsiyani amalga oshirishini yoki hammasi uni to'xtatishini ta'minlaydi va shu bilan ma'lumotlar izchilligini saqlaydi. Bu bizga kerak bo'lgan narsaga o'xshaydi, lekin ikki fazali majburiyatning bir nechta kamchiliklari bor:
Mikroservislar arxitekturasi uchun eng aniq yechim naqsh (yoki hatto ba'zan anti-pattern) - umumiy ma'lumotlar bazasini qo'llashdir. Agar sizga turli ma'lumotlar bazalaridagi bir nechta jadvallar bo'yicha tranzaksiyaviy izchillik kerak bo'lsa, bu yondashuv juda intuitivdir, bu mikroservislar uchun faqat bitta umumiy ma'lumotlar bazasidan foydalaning.
Ushbu yondashuvning kamchiliklari orasida bitta nosozlik nuqtasini kiritish, ma'lumotlar bazasini mustaqil masshtablashni taqiqlash va muayyan talablar va foydalanish holatlari uchun eng mos keladigan turli xil ma'lumotlar bazasi echimlaridan foydalanish imkoniyatini cheklash kiradi. Bundan tashqari, taqsimlangan tranzaktsiyaning bunday shaklini qo'llab-quvvatlash uchun mikroservislar kod bazalariga o'zgartirishlar kiritish kerak bo'ladi.
" Tranzaksiya chiquvchi qutisi " - bu hatto ishonchsiz xabar almashish tizimlarida ham ishonchli xabar tarqalishini ta'minlash uchun taqsimlangan tizimlarda qo'llaniladigan dizayn namunasidir. U voqealarni operatsiyaning o'zi bilan bir xil tranzaksiya doirasida belgilangan "OutboxEvents" jadvalida saqlashni o'z ichiga oladi. Ushbu yondashuv relyatsion ma'lumotlar bazalarining ACID xususiyatlariga yaxshi mos keladi. Aksincha, ko'pgina No-SQL ma'lumotlar bazalari ACID xususiyatlarini to'liq qo'llab-quvvatlamaydi, buning o'rniga CAP teoremasi va BASE falsafasi tamoyillarini tanlaydi, ular qat'iy izchillikdan ko'ra mavjudlik va yakuniy izchillikni birinchi o'ringa qo'yadi.
Tranzaksiya chiqish qutisi kamida bir marta kafolat beradi va bir nechta yondashuvlar bilan amalga oshirilishi mumkin:
Tranzaksiya jurnali qoldig'i
So'rovnoma nashriyotchisi
Tranzaksiya jurnalini saqlash yondashuvi CDC (Ma'lumotlarni yozib olishni o'zgartirish) kabi ma'lumotlar bazasiga xos echimlardan foydalanishni nazarda tutadi. Ushbu yondashuvning asosiy kamchiliklari:
Ma'lumotlar bazasi uchun maxsus echimlar
CDC ilovalarining o'ziga xos xususiyatlari tufayli kechikishning oshishi
Yana bir usul - Polling Publisher , bu chiqish qutisi jadvalini so'rash orqali chiquvchi xabarlarni yuklashni osonlashtiradi. Ushbu yondashuvning asosiy kamchiligi ma'lumotlar bazasi yuklanishining ortishi ehtimoli bo'lib, bu yuqori xarajatlarga olib kelishi mumkin. Bundan tashqari, barcha No-SQL ma'lumotlar bazalari muayyan hujjat segmentlari uchun samarali so'rovlarni qo'llab-quvvatlamaydi. Hujjatlarni to'liq chiqarib olish, shuning uchun ishlashning pasayishiga olib kelishi mumkin.
Bu qanday ishlashini tushuntiruvchi kichik ketma-ketlik diagrammasi.
Transactional Outbox naqshining asosiy muammosi uning ma'lumotlar bazasining ACID xususiyatlariga bog'liqligidadir. Bu odatiy OLTP ma'lumotlar bazalarida oddiy bo'lishi mumkin, ammo NoSQL sohasida qiyinchiliklar tug'diradi. Buni hal qilish uchun potentsial yechim so'rovni qayta ishlashni boshlashdanoq qo'shish jurnalidan (masalan, Kafka) foydalanishdir.
"Kredit arizasini yuborish" buyrug'ini to'g'ridan-to'g'ri qayta ishlash o'rniga, biz uni darhol ichki Kafka mavzusiga yuboramiz va keyin mijozga "qabul qilingan" natijani qaytaramiz. Biroq, buyruq hali ham qayta ishlanishi kerakligi sababli, mijozga natija haqida darhol xabar bera olmaymiz. Ushbu yakuniy izchillikni boshqarish uchun biz uzoq so'rovlar, mijoz tomonidan boshlangan so'rovlar, optimistik UI yangilanishlari yoki bildirishnomalar uchun WebSockets yoki Server tomonidan yuborilgan voqealardan foydalanish kabi usullardan foydalanishimiz mumkin. Biroq, bu mutlaqo alohida mavzu, shuning uchun keling, boshlang'ich mavzuimizga qaytaylik.
Biz xabarni ichki Kafka mavzusida yubordik. So'ngra Kreditga ariza berish xizmati ushbu xabarni iste'mol qiladi - mijozdan olgan xuddi shu buyruq - va qayta ishlashni boshlaydi. Birinchidan, u ba'zi biznes mantig'ini bajaradi; faqat ushbu mantiq muvaffaqiyatli bajarilgandan va natijalar saqlanib qolgandan so'ng, u umumiy Kafka mavzusida yangi xabarlarni nashr etadi.
Keling, bir oz psevdo-kodni ko'rib chiqaylik.
public async Task HandleAsync(SubmitLoanApplicationCommand command, ...) { //First, process business logic var loanApplication = await _loanApplicationService.HandleCommandAsync(command, ...); //Then, send new events to public Kafka topic producer.Send(new LoanApplicationSubmittedEvent(loanApplication.Id)); //Then, commit offset consumer.Commit(); }
Agar biznes mantig'ini qayta ishlash muvaffaqiyatsiz tugasa nima bo'ladi? Xavotir olmang, ofset hali amalga oshirilmagani uchun xabar qayta ko'rib chiqiladi.
Agar Kafkaga yangi voqealar yuborilmasa-chi? Xavotir olmang, biznes mantig'i idempotent bo'lgani uchun u dublikat kredit arizasini yaratmaydi. Buning o'rniga u xabarlarni umumiy Kafka mavzusiga qayta yuborishga harakat qiladi.
Agar xabarlar Kafkaga yuborilsa-chi, lekin ofset majburiyati bajarilmasa? Xavotir olmang, chunki biznes mantig'i idempotent bo'lgani uchun u dublikat kredit arizasini yaratmaydi. Buning o'rniga, u ommaviy Kafka mavzusiga xabarlarni qayta yuboradi va bu safar ofset majburiyati muvaffaqiyatli bo'lishiga umid qiladi.
Ushbu yondashuvning asosiy kamchiliklari yangi dasturlash uslubi bilan bog'liq qo'shimcha murakkablik, yakuniy izchillik (chunki mijoz natijani darhol bilmaydi) va barcha biznes mantig'ining idempotent bo'lishi talabini o'z ichiga oladi.
Voqealar manbasi nima va u bu erda qanday qo'llanilishi mumkin? Voqealar manbasi - bu tizimning holatini uning ma'lumotlaridagi barcha o'zgarishlarni bir qator o'zgarmas hodisalar sifatida qo'lga kiritish orqali modellashtirish uchun foydalaniladigan dasturiy ta'minot arxitektura naqshidir. Ushbu hodisalar faktlar yoki holat o'tishlarini ifodalaydi va tizimning hozirgi holati uchun yagona haqiqat manbai bo'lib xizmat qiladi. Shunday qilib, texnik jihatdan, voqea manbalarini aniqlash tizimini joriy qilish orqali bizda allaqachon EventStore-da barcha voqealar mavjud va bu EventStore iste'molchilar tomonidan sodir bo'lgan voqea haqida yagona haqiqat manbai sifatida foydalanishi mumkin. Buyurtma bilan bog'liq barcha o'zgarishlar yoki tashvishlarni kuzatish uchun ma'lum bir ma'lumotlar bazasi echimiga ehtiyoj yo'q, yagona muammo - o'qish tomonida o'tirish, chunki ob'ektning haqiqiy holatini olish uchun barcha voqealarni takrorlash talab qilinadi.
Ushbu maqolada biz tarqatilgan tizimlarda ishonchli xabar almashishni yaratish uchun bir nechta yondashuvlarni ko'rib chiqdik. Ushbu xususiyatlarga ega tizimlarni qurishda bir nechta tavsiyalarni ko'rib chiqishimiz mumkin
Keyingi safar biz Transactional Outbox-ni amalga oshirishning amaliy misolini ko'rib chiqamiz. Qarang
sen!