Monolitdan mikroservislarga o'tish: tarix va amaliyot

Ushbu maqolada men ishlayotgan loyiham qanday qilib katta monolitdan mikroservislar to'plamiga aylantirilgani haqida gapiraman.

Loyiha oʻz tarixini ancha oldin, 2000-yil boshida boshlagan. Birinchi versiyalari Visual Basic 6 da yozilgan. Vaqt oʻtishi bilan bu tilni rivojlantirish kelajakda qoʻllab-quvvatlash qiyin boʻlishi maʼlum boʻldi, chunki IDE. tilning o‘zi esa sust rivojlangan. 2000-yillarning oxirida yanada istiqbolli C# ga o'tishga qaror qilindi. Yangi versiya eskisini qayta ko'rib chiqish bilan parallel ravishda yozildi, asta-sekin .NET-da ko'proq kod yozildi. C# da backend dastlab xizmat arxitekturasiga qaratilgan edi, lekin ishlab chiqish jarayonida mantiqqa ega umumiy kutubxonalardan foydalanildi va xizmatlar yagona jarayonda ishga tushirildi. Natijada biz "xizmat monolit" deb ataydigan dastur paydo bo'ldi.

Ushbu kombinatsiyaning bir nechta afzalliklaridan biri xizmatlarning tashqi API orqali bir-biriga qo'ng'iroq qilish qobiliyati edi. To'g'riroq xizmatga, kelajakda esa mikroservis arxitekturasiga o'tish uchun aniq shartlar mavjud edi.

Biz parchalanish bo'yicha ishimizni 2015 yilda boshladik. Biz hali ideal holatga erishganimiz yo‘q – hali ham yirik loyihaning monolit deb atash mumkin bo‘lmagan qismlari bor, lekin ular ham mikroservislarga o‘xshamaydi. Shunga qaramay, taraqqiyot sezilarli.
Men bu haqda maqolada gaplashaman.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Mundarija

Arxitektura va mavjud yechim muammolari


Dastlab, arxitektura shunday ko'rinishga ega edi: UI alohida dastur, monolit qismi Visual Basic 6 da yozilgan, .NET ilovasi juda katta ma'lumotlar bazasi bilan ishlaydigan tegishli xizmatlar to'plamidir.

Oldingi yechimning kamchiliklari

Bitta muvaffaqiyatsizlik nuqtasi
Bizda bitta xato nuqtasi bor edi: .NET ilovasi bitta jarayonda ishladi. Agar biron bir modul muvaffaqiyatsiz bo'lsa, butun dastur muvaffaqiyatsiz tugadi va uni qayta ishga tushirish kerak edi. Biz turli xil foydalanuvchilar uchun ko'p sonli jarayonlarni avtomatlashtirganimiz sababli, ulardan birida nosozlik tufayli hamma ham bir muncha vaqt ishlay olmadi. Va dasturiy ta'minot xatosi bo'lsa, hatto zaxira nusxasi ham yordam bermadi.

Yaxshilashlar navbati
Bu kamchilik ancha tashkiliy xususiyatga ega. Bizning ilovamiz ko'plab mijozlarga ega va ularning barchasi uni imkon qadar tezroq yaxshilashni xohlaydi. Ilgari buni parallel ravishda amalga oshirish mumkin emas edi va barcha mijozlar navbatda turishdi. Bu jarayon korxonalar uchun salbiy edi, chunki ular o'z vazifasi qimmatli ekanligini isbotlashlari kerak edi. Va ishlab chiqish guruhi bu navbatni tashkil qilish uchun vaqt sarfladi. Bu juda ko'p vaqt va kuch talab qildi va mahsulot oxir-oqibat ular xohlagancha tez o'zgarmadi.

Resurslardan suboptimal foydalanish
Xizmatlarni bitta jarayonda joylashtirishda biz har doim konfiguratsiyani serverdan serverga to'liq ko'chirdik. Biz resurslarni isrof qilmaslik va joylashtirish sxemamiz ustidan yanada moslashuvchan nazoratga ega bo'lish uchun eng og'ir yuklangan xizmatlarni alohida joylashtirishni xohladik.

Zamonaviy texnologiyalarni joriy etish qiyin
Barcha ishlab chiquvchilarga tanish bo'lgan muammo: loyihaga zamonaviy texnologiyalarni joriy etish istagi bor, ammo imkoniyat yo'q. Katta monolit yechim bilan hozirgi kutubxonaning har qanday yangilanishi, yangisiga o'tish haqida gapirmasa ham, juda ahamiyatsiz bo'lgan vazifaga aylanadi. Bu behuda nervlardan ko'ra ko'proq bonus olib kelishini jamoa rahbariga isbotlash uchun uzoq vaqt kerak bo'ladi.

O'zgarishlarni chiqarishda qiyinchilik
Bu eng jiddiy muammo edi - biz har ikki oyda relizlar chiqarardik.
Ishlab chiquvchilarning sinovlari va sa'y-harakatlariga qaramay, har bir nashr bank uchun haqiqiy falokatga aylandi. Biznes hafta boshida uning ba'zi funksiyalari ishlamasligini tushundi. Ishlab chiquvchilar esa ularni bir hafta jiddiy voqealar kutayotganini tushunishdi.
Hammada vaziyatni o'zgartirish istagi bor edi.

Mikroservislardan umidlar


Tayyor bo'lganda komponentlarning chiqarilishi. Eritmani parchalash va turli jarayonlarni ajratish orqali tayyor bo'lganda komponentlarni etkazib berish.

Kichik mahsulot guruhlari. Bu juda muhim, chunki eski monolitda ishlaydigan katta jamoani boshqarish qiyin edi. Bunday jamoa qat'iy jarayon bo'yicha ishlashga majbur edi, lekin ular ko'proq ijodkorlik va mustaqillikni xohladilar. Bunga faqat kichik jamoalar qodir edi.

Xizmatlarni alohida jarayonlarda izolyatsiya qilish. Ideal holda, men uni konteynerlarda ajratib qo'ymoqchiman, lekin .NET Frameworkda yozilgan ko'plab xizmatlar faqat ostida ishlaydi Windows.NET Core asosidagi xizmatlar endi paydo bo'lmoqda, ammo ular hali ham oz.

Joylashtirishning moslashuvchanligi. Biz xizmatlarni kod talab qiladigan tarzda emas, balki kerakli tarzda birlashtirmoqchimiz.

Yangi texnologiyalardan foydalanish. Bu har qanday dasturchi uchun qiziqarli.

O'tish muammolari


Albatta, agar monolitni mikroservislarga ajratish oson bo'lsa, bu haqda konferentsiyalarda gapirish va maqolalar yozish kerak emas edi. Bu jarayonda ko'plab tuzoqlar mavjud, men bizga to'sqinlik qilgan asosiylarini tasvirlab beraman.

Birinchi muammo ko'pchilik monolitlarga xos: biznes mantig'ining uyg'unligi. Biz monolit yozganimizda, keraksiz kod yozmaslik uchun sinflarimizni qayta ishlatmoqchimiz. Va mikroservislarga o'tishda bu muammoga aylanadi: barcha kodlar juda qattiq bog'langan va xizmatlarni ajratish qiyin.

Ish boshlanganda omborda 500 dan ortiq loyihalar va 700 mingdan ortiq kod satrlari mavjud edi. Bu juda katta qaror va ikkinchi muammo. Uni oddiygina qabul qilib, mikroservislarga bo'lish mumkin emas edi.

Uchinchi muammo — zarur infratuzilmaning yo‘qligi. Aslida, biz manba kodini serverlarga qo'lda nusxa ko'chirdik.

Monolitdan mikroservislarga qanday o'tish mumkin


Mikroservislarni ta'minlash

Birinchidan, biz darhol o'zimiz uchun mikroservislarni ajratish iterativ jarayon ekanligini aniqladik. Bizdan doimo parallel ravishda biznes muammolarini ishlab chiqish talab qilingan. Buni texnik jihatdan qanday amalga oshirishimiz allaqachon bizning muammomiz. Shuning uchun biz iterativ jarayonga tayyorlandik. Agar sizda katta dastur bo'lsa va u dastlab qayta yozishga tayyor bo'lmasa, u boshqa yo'l bilan ishlamaydi.

Mikroservislarni ajratish uchun qanday usullardan foydalanamiz?

birinchi usul — mavjud modullarni xizmatlar sifatida ko'chirish. Shu nuqtai nazardan, bizga omad kulib boqdi: WCF protokoli yordamida ishlaydigan ro'yxatdan o'tgan xizmatlar allaqachon mavjud edi. Ular alohida yig'ilishlarga bo'lingan. Biz ularni alohida-alohida joylashtirdik va har bir qurilmaga kichik ishga tushirish moslamasini qo'shdik. U ajoyib Topshelf kutubxonasidan foydalangan holda yozilgan bo'lib, u ilovani ham xizmat, ham konsol sifatida ishlatish imkonini beradi. Bu nosozliklarni tuzatish uchun qulay, chunki yechimda qo'shimcha loyihalar talab qilinmaydi.

Xizmatlar biznes mantig'iga ko'ra ulangan, chunki ular umumiy yig'ilishlardan foydalangan va umumiy ma'lumotlar bazasi bilan ishlagan. Ularni sof shaklda mikroservislar deb atash qiyin. Biroq, biz ushbu xizmatlarni alohida, turli jarayonlarda taqdim etishimiz mumkin edi. Buning o'zi ularning bir-biriga ta'sirini kamaytirishga imkon berdi, parallel rivojlanish va yagona muvaffaqiyatsizlik nuqtasi bilan muammoni kamaytirdi.

Xost bilan yig'ilish bu Dastur sinfidagi kodning faqat bitta qatoridir. Biz Topshelf bilan ishlashni yordamchi sinfda yashirdik.

namespace RBA.Services.Accounts.Host
{
   internal class Program
   {
      private static void Main(string[] args)
      {
        HostRunner<Accounts>.Run("RBA.Services.Accounts.Host");

       }
    }
}

Mikroservislarni taqsimlashning ikkinchi usuli: yangi muammolarni hal qilish uchun ularni yaratish. Agar bir vaqtning o'zida monolit o'smasa, bu juda yaxshi, ya'ni biz to'g'ri yo'nalishda harakat qilamiz. Yangi muammolarni hal qilish uchun biz alohida xizmatlarni yaratishga harakat qildik. Agar bunday imkoniyat mavjud bo'lsa, biz o'zlarining ma'lumotlar modelini, alohida ma'lumotlar bazasini to'liq boshqaradigan ko'proq "kanonik" xizmatlarni yaratdik.

Biz, ko'pchilik singari, autentifikatsiya va avtorizatsiya xizmatlaridan boshladik. Buning uchun ular mukammaldir. Ular mustaqil, qoida tariqasida, alohida ma'lumotlar modeliga ega. Ularning o'zlari monolit bilan o'zaro ta'sir qilmaydi, faqat ba'zi muammolarni hal qilish uchun ularga murojaat qiladi. Ushbu xizmatlardan foydalanib, siz yangi arxitekturaga o'tishni boshlashingiz, ulardagi infratuzilmani disk raskadrovka qilishingiz, tarmoq kutubxonalari bilan bog'liq ba'zi yondashuvlarni sinab ko'rishingiz mumkin va hokazo. Tashkilotimizda autentifikatsiya xizmatini yarata olmagan jamoalar yo‘q.

Mikroservislarni ajratishning uchinchi usuliBiz foydalanadigan narsa bizga biroz xosdir. Bu UI qatlamidan biznes mantig'ini olib tashlashdir. Bizning asosiy UI ilovamiz ish stoli bo'lib, u xuddi backend kabi C# da yozilgan. Ishlab chiquvchilar vaqti-vaqti bilan xatolarga yo'l qo'yishdi va mantiq qismlarini UIga o'tkazdilar, ular backendda mavjud bo'lishi va qayta ishlatilishi kerak edi.

Agar siz UI qismi kodidan haqiqiy misolni ko'rsangiz, ushbu yechimning aksariyati faqat UI shaklini yaratish uchun emas, balki boshqa jarayonlarda ham foydali bo'lgan haqiqiy biznes mantiqini o'z ichiga olganligini ko'rishingiz mumkin.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Haqiqiy UI mantig'i faqat oxirgi ikki qatorda mavjud. Biz uni qayta ishlatish uchun serverga o'tkazdik, shu bilan UIni qisqartirdik va to'g'ri arxitekturaga erishdik.

Mikroservislarni izolyatsiya qilishning to'rtinchi va eng muhim usuli, bu monolitni kamaytirishga imkon beradi, bu mavjud xizmatlarni qayta ishlash bilan olib tashlashdir. Mavjud modullarni o'z holicha olib tashlasak, natija har doim ham ishlab chiquvchilarga yoqmaydi va biznes jarayoni funksionallik yaratilganidan beri eskirgan bo'lishi mumkin. Refaktoring yordamida biz yangi biznes jarayonini qo'llab-quvvatlay olamiz, chunki biznes talablari doimo o'zgarib turadi. Biz manba kodini yaxshilashimiz, ma'lum bo'lgan kamchiliklarni bartaraf etishimiz va yaxshiroq ma'lumotlar modelini yaratishimiz mumkin. Ko'p foyda keltiradi.

Xizmatlarni qayta ishlashdan ajratish chegaralangan kontekst tushunchasi bilan uzviy bog'liqdir. Bu Domain Driven Design kompaniyasining kontseptsiyasi. Bu bitta tilning barcha atamalari yagona aniqlangan domen modelining bo'limini anglatadi. Misol tariqasida sug'urta va veksellar kontekstini ko'rib chiqamiz. Bizda monolit dastur bor va biz sug'urtada hisob bilan ishlashimiz kerak. Biz ishlab chiquvchidan boshqa assambleyada mavjud Hisob sinfini topishini, unga Sug‘urta sinfidan havola qilishini kutamiz va bizda ishchi kod bo‘ladi. DRY printsipi hurmat qilinadi, vazifa mavjud kod yordamida tezroq amalga oshiriladi.

Natijada, hisob va sug'urta kontekstlari bog'langanligi ma'lum bo'ldi. Yangi talablar paydo bo'lganda, bu bog'lanish rivojlanishga xalaqit beradi va allaqachon murakkab biznes mantig'ining murakkabligini oshiradi. Ushbu muammoni hal qilish uchun siz koddagi kontekstlar orasidagi chegaralarni topishingiz va ularning buzilishlarini olib tashlashingiz kerak. Misol uchun, sug'urta kontekstida Markaziy bankning 20 xonali hisob raqami va hisob ochilgan sana etarli bo'lishi mumkin.

Ushbu chegaralangan kontekstlarni bir-biridan ajratish va mikroservislarni monolit yechimdan ajratish jarayonini boshlash uchun biz ilova ichida tashqi API yaratish kabi yondashuvdan foydalandik. Agar biz ba'zi modul mikroservisga aylanishi kerakligini bilsak, jarayon davomida qandaydir tarzda o'zgartirilgan bo'lsak, biz darhol tashqi qo'ng'iroqlar orqali boshqa cheklangan kontekstga tegishli mantiqqa qo'ng'iroqlar qildik. Masalan, REST yoki WCF orqali.

Biz taqsimlangan tranzaktsiyalarni talab qiladigan koddan qochmaslikka qat'iy qaror qildik. Bizning holatda, bu qoidaga amal qilish juda oson bo'lib chiqdi. Biz hali qat'iy taqsimlangan tranzaktsiyalar zarur bo'lgan holatlarga duch kelmadik - modullar orasidagi yakuniy muvofiqlik juda etarli.

Keling, aniq bir misolni ko'rib chiqaylik. Bizda orkestr tushunchasi bor - bu "ilova" ob'ektini qayta ishlaydigan quvur liniyasi. U o'z navbatida mijoz, hisob va bank kartasini yaratadi. Agar mijoz va hisob qaydnomasi muvaffaqiyatli yaratilgan bo'lsa, lekin kartani yaratish muvaffaqiyatsiz tugasa, dastur "muvaffaqiyatli" holatiga o'tmaydi va "karta yaratilmagan" holatida qoladi. Kelajakda fon faoliyati uni olib, tugatadi. Tizim bir muncha vaqtdan beri nomuvofiqlik holatida edi, lekin biz odatda bundan mamnunmiz.

Agar ma'lumotlarning bir qismini doimiy ravishda saqlash zarur bo'lgan vaziyat yuzaga kelsa, biz uni bir jarayonda qayta ishlash uchun xizmatni birlashtirishga o'tamiz.

Keling, mikroservisni ajratish misolini ko'rib chiqaylik. Qanday qilib uni nisbatan xavfsiz ishlab chiqarishga olib kelish mumkin? Ushbu misolda bizda tizimning alohida qismi bor - ish haqi bo'yicha xizmat ko'rsatish moduli, kod bo'limlaridan biri biz mikroservis qilishni xohlaymiz.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Avvalo, kodni qayta yozish orqali mikroservis yaratamiz. Biz mamnun bo'lmagan ba'zi jihatlarni yaxshilayapmiz. Biz mijozdan yangi biznes talablarini amalga oshiramiz. UI va backend o'rtasidagi aloqaga API shlyuzini qo'shamiz, u qo'ng'iroqlarni boshqa raqamga yo'naltirishni ta'minlaydi.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Keyinchalik, biz ushbu konfiguratsiyani ishga tushiramiz, lekin sinov holatida. Ko'pchilik foydalanuvchilarimiz hali ham eski biznes jarayonlari bilan ishlaydi. Yangi foydalanuvchilar uchun biz monolit dasturning yangi versiyasini ishlab chiqmoqdamiz, u endi bu jarayonni o'z ichiga olmaydi. Aslida, bizda monolit va mikroservisning kombinatsiyasi uchuvchi sifatida ishlaydi.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Muvaffaqiyatli uchuvchi bilan biz yangi konfiguratsiya haqiqatan ham ishlashi mumkinligini tushunamiz, biz tenglamadan eski monolitni olib tashlashimiz va eski yechim o'rniga yangi konfiguratsiyani qoldirishimiz mumkin.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Umuman olganda, biz monolitning manba kodini bo'lish uchun deyarli barcha mavjud usullardan foydalanamiz. Ularning barchasi bizga dastur qismlarining hajmini qisqartirish va ularni yangi kutubxonalarga tarjima qilish, yaxshi manba kodini yaratish imkonini beradi.

Ma'lumotlar bazasi bilan ishlash


Ma'lumotlar bazasini manba kodidan ko'ra yomonroq bo'lish mumkin, chunki u nafaqat joriy sxemani, balki to'plangan tarixiy ma'lumotlarni ham o'z ichiga oladi.

Bizning ma'lumotlar bazasi, boshqalar kabi, yana bir muhim kamchilikka ega edi - uning katta hajmi. Ushbu ma'lumotlar bazasi monolitning murakkab biznes mantig'iga ko'ra ishlab chiqilgan va turli xil chegaralangan kontekstlarning jadvallari o'rtasida to'plangan munosabatlar.

Bizning holatda, barcha muammolarni (katta ma'lumotlar bazasi, ko'plab ulanishlar, ba'zan jadvallar orasidagi aniq chegaralar) engish uchun ko'plab yirik loyihalarda yuzaga keladigan muammo paydo bo'ldi: umumiy ma'lumotlar bazasi shablonidan foydalanish. Ma'lumotlar jadvallardan ko'rinish, replikatsiya orqali olindi va bu replikatsiya zarur bo'lgan boshqa tizimlarga yuborildi. Natijada, biz jadvallarni alohida sxemaga ko'chira olmadik, chunki ular faol ishlatilgan.

Koddagi cheklangan kontekstlarga bir xil bo'linish bizga ajratishda yordam beradi. Odatda bu bizga ma'lumotlar bazasi darajasida ma'lumotlarni qanday parchalashimiz haqida juda yaxshi fikr beradi. Biz qaysi jadvallar bir chegaralangan kontekstga va qaysi biri boshqasiga tegishli ekanligini tushunamiz.

Biz ma'lumotlar bazasini bo'lishning ikkita global usulidan foydalandik: mavjud jadvallarni bo'lish va ishlov berish bilan bo'lish.

Mavjud jadvallarni ajratish, agar ma'lumotlar tuzilmasi yaxshi bo'lsa, biznes talablariga javob bersa va hamma bundan mamnun bo'lsa, foydalanish uchun yaxshi usuldir. Bunday holda, biz mavjud jadvallarni alohida sxemaga ajratishimiz mumkin.

Biznes modeli juda o'zgarganda va jadvallar bizni umuman qoniqtirmasa, qayta ishlash bo'limi kerak bo'ladi.

Mavjud jadvallarni ajratish. Biz nimani ajratishimizni aniqlashimiz kerak. Ushbu bilimsiz hech narsa ishlamaydi va bu erda koddagi cheklangan kontekstlarni ajratish bizga yordam beradi. Qoidaga ko'ra, agar siz manba kodidagi kontekstlarning chegaralarini tushunsangiz, bo'lim uchun qaysi jadvallar ro'yxatiga kiritilishi kerakligi aniq bo'ladi.

Tasavvur qilaylik, bizda ikkita monolit modul bitta ma'lumotlar bazasi bilan o'zaro ta'sir qiladigan echim bor. Biz faqat bitta modul ajratilgan jadvallar bo'limi bilan o'zaro aloqada bo'lishiga ishonch hosil qilishimiz kerak, ikkinchisi esa API orqali u bilan o'zaro ta'sir qila boshlaydi. Boshlash uchun faqat API orqali yozishni amalga oshirish kifoya. Bu mikroservislarning mustaqilligi haqida gapirishimiz uchun zaruriy shartdir. Katta muammo bo'lmasa, o'qish ulanishlari qolishi mumkin.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Keyingi qadam shundaki, biz kodning ajratilgan jadvallar bilan ishlaydigan, qayta ishlanmasdan yoki ishlamasdan alohida mikroservisga ajratishimiz va uni alohida jarayonda, konteynerda ishga tushirishimiz mumkin. Bu monolit ma'lumotlar bazasiga va unga to'g'ridan-to'g'ri aloqasi bo'lmagan jadvallarga ulangan alohida xizmat bo'ladi. Monolit hali ham ajraladigan qism bilan o'qish uchun o'zaro ta'sir qiladi.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Keyinchalik biz ushbu ulanishni olib tashlaymiz, ya'ni ajratilgan jadvallardan monolit ilovadan o'qish ma'lumotlari ham API-ga o'tkaziladi.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Keyinchalik, umumiy ma'lumotlar bazasidan faqat yangi mikroservis ishlaydigan jadvallarni tanlaymiz. Biz jadvallarni alohida sxemaga yoki hatto alohida jismoniy ma'lumotlar bazasiga ko'chirishimiz mumkin. Mikroservis va monolit ma'lumotlar bazasi o'rtasida hali ham o'qish aloqasi mavjud, ammo tashvishlanadigan hech narsa yo'q, bu konfiguratsiyada u juda uzoq vaqt yashashi mumkin.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Oxirgi qadam barcha ulanishlarni butunlay olib tashlashdir. Bunday holda, biz asosiy ma'lumotlar bazasidan ma'lumotlarni ko'chirishimiz kerak bo'lishi mumkin. Ba'zan biz bir nechta ma'lumotlar bazalarida tashqi tizimlardan takrorlangan ba'zi ma'lumotlar yoki kataloglarni qayta ishlatishni xohlaymiz. Bu biz bilan vaqti-vaqti bilan sodir bo'ladi.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Qayta ishlash bo'limi. Bu usul birinchisiga juda o'xshaydi, faqat teskari tartibda. Biz darhol yangi ma'lumotlar bazasini va API orqali monolit bilan o'zaro ta'sir qiluvchi yangi mikroservisni ajratamiz. Ammo shu bilan birga, biz kelajakda o'chirmoqchi bo'lgan ma'lumotlar bazasi jadvallari to'plami qoladi. Bizga endi kerak emas, biz uni yangi modelga almashtirdik.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Ushbu sxema ishlashi uchun bizga o'tish davri kerak bo'ladi.

Keyin ikkita mumkin bo'lgan yondashuv mavjud.

birinchi: biz yangi va eski ma'lumotlar bazalaridagi barcha ma'lumotlarni takrorlaymiz. Bunday holda, bizda ma'lumotlar ortiqcha va sinxronizatsiya muammolari paydo bo'lishi mumkin. Lekin biz ikki xil mijozni qabul qilishimiz mumkin. Biri yangi versiya bilan, ikkinchisi eskisi bilan ishlaydi.

ikkinchi: biz ma'lumotlarni ba'zi biznes mezonlari bo'yicha ajratamiz. Misol uchun, bizda eski ma'lumotlar bazasida saqlangan tizimda 5 ta mahsulot bor edi. Biz yangi ma'lumotlar bazasiga yangi biznes vazifasi doirasida oltinchini joylashtiramiz. Ammo bizga ushbu ma'lumotlarni sinxronlashtiradigan va mijozga qayerdan va nimani olishni ko'rsatadigan API shlyuzi kerak bo'ladi.

Ikkala yondashuv ham ishlaydi, vaziyatga qarab tanlang.

Har bir narsa ishlayotganiga amin bo'lganimizdan so'ng, eski ma'lumotlar bazasi tuzilmalari bilan ishlaydigan monolit qismini o'chirib qo'yish mumkin.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Oxirgi qadam eski ma'lumotlar tuzilmalarini olib tashlashdir.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Xulosa qilib aytadigan bo'lsak, bizda ma'lumotlar bazasi bilan bog'liq muammolar borligini aytishimiz mumkin: manba kodiga nisbatan u bilan ishlash qiyin, uni almashish qiyinroq, lekin buni qilish mumkin va kerak. Biz buni xavfsiz bajarishga imkon beradigan ba'zi usullarni topdik, ammo manba kodidan ko'ra ma'lumotlar bilan xato qilish osonroq.

Manba kodi bilan ishlash


Monolit loyihani tahlil qilishni boshlaganimizda manba kodi diagrammasi shunday ko'rinishga ega edi.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Taxminan uchta qatlamga bo'linishi mumkin. Bu ishga tushirilgan modullar, plaginlar, xizmatlar va individual harakatlar qatlami. Aslida, bu monolitik yechim ichidagi kirish nuqtalari edi. Ularning barchasi Umumiy qatlam bilan mahkam yopilgan. Unda xizmatlar almashadigan biznes mantig'i va ko'plab ulanishlar mavjud edi. Har bir xizmat va plagin hajmi va ishlab chiquvchilarning vijdoniga qarab 10 tagacha yoki undan ko'p umumiy yig'ilishlardan foydalanilgan.

Bizga alohida foydalanish mumkin bo'lgan infratuzilma kutubxonalari borligi baxtiyor edi.

Ba'zida shunday vaziyat yuzaga keldiki, ba'zi umumiy ob'ektlar aslida ushbu qatlamga tegishli emas, balki infratuzilma kutubxonalari edi. Bu nomni o'zgartirish orqali hal qilindi.

Eng katta tashvish chegaralangan kontekstlar edi. Bitta Umumiy yig'ilishda 3-4 kontekst aralashtirilgan va bir xil biznes funktsiyalari doirasida bir-biridan foydalangan. Buni qaerga va qanday chegaralar bo'ylab ajratish mumkinligini va bu bo'linishni manba kodlari yig'ilishlariga joylashtirish bilan nima qilish kerakligini tushunish kerak edi.

Biz kodni ajratish jarayoni uchun bir nechta qoidalarni ishlab chiqdik.

birinchi: Biz endi xizmatlar, faoliyat va plaginlar o'rtasida biznes mantig'ini bo'lishishni xohlamadik. Biz mikroservislar doirasida biznes mantig'ini mustaqil qilishni xohladik. Boshqa tomondan, mikroservislar mutlaqo mustaqil ravishda mavjud bo'lgan xizmatlar sifatida ko'rib chiqiladi. Menimcha, bu yondashuv biroz isrofgarchilik va bunga erishish qiyin, chunki, masalan, C# tilidagi xizmatlar har qanday holatda ham standart kutubxona orqali ulanadi. Bizning tizimimiz C# tilida yozilgan, biz hali boshqa texnologiyalardan foydalanmadik. Shuning uchun biz umumiy texnik yig'ilishlardan foydalanishimiz mumkinligiga qaror qildik. Asosiysi, ularda biznes mantig'ining hech qanday bo'laklari mavjud emas. Agar siz foydalanayotgan ORM ustidan qulaylik paketiga ega bo'lsangiz, uni xizmatdan xizmatga nusxalash juda qimmatga tushadi.

Bizning jamoamiz domenga asoslangan dizaynning muxlisidir, shuning uchun piyoz arxitekturasi biz uchun juda mos edi. Bizning xizmatlarimizning asosi ma'lumotlarga kirish qatlami emas, balki faqat biznes mantig'ini o'z ichiga olgan va infratuzilma bilan aloqasi bo'lmagan domen mantig'iga ega yig'ilishdir. Shu bilan birga, biz ramkalar bilan bog'liq muammolarni hal qilish uchun domen yig'ilishini mustaqil ravishda o'zgartirishimiz mumkin.

Ushbu bosqichda biz birinchi jiddiy muammoga duch keldik. Xizmat bitta domen yig'ilishiga murojaat qilishi kerak edi, biz mantiqni mustaqil qilishni xohladik va DRY printsipi bu erda bizga katta xalaqit berdi. Ishlab chiquvchilar takrorlanishning oldini olish uchun qo'shni yig'ilishlardagi sinflarni qayta ishlatmoqchi bo'lishdi va natijada domenlar yana bir-biriga bog'lana boshladi. Biz natijalarni tahlil qildik va ehtimol muammo manba kodini saqlash qurilmasi sohasida ham borligiga qaror qildik. Bizda barcha manba kodlarini o'z ichiga olgan katta omborimiz bor edi. Butun loyiha uchun yechimni mahalliy mashinada yig'ish juda qiyin edi. Shuning uchun, loyihaning qismlari uchun alohida kichik echimlar yaratilgan va hech kim ularga umumiy yoki domen yig'ilishini qo'shishni va ularni qayta ishlatishni taqiqlamagan. Buni amalga oshirishga imkon bermagan yagona vosita bu kodni tekshirish edi. Ammo ba'zida bu ham muvaffaqiyatsizlikka uchradi.

Keyin biz alohida omborlarga ega modelga o'tishni boshladik. Biznes mantig'i endi xizmatdan xizmatga o'tmaydi, domenlar haqiqatan ham mustaqil bo'lib qoldi. Cheklangan kontekstlar aniqroq qo'llab-quvvatlanadi. Infratuzilma kutubxonalaridan qanday foydalanamiz? Biz ularni alohida omborga ajratdik, keyin ularni Nuget paketlariga joylashtirdik, ularni Artifactory-ga joylashtirdik. Har qanday o'zgarish bilan, yig'ish va nashr avtomatik ravishda sodir bo'ladi.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Bizning xizmatlarimiz tashqi infratuzilma paketlari kabi ichki infratuzilma paketlariga murojaat qila boshladi. Nuget-dan tashqi kutubxonalarni yuklab olamiz. Ushbu paketlarni joylashtirgan Artifactory bilan ishlash uchun biz ikkita paket menejeridan foydalandik. Kichik omborlarda biz Nuget-dan ham foydalanardik. Bir nechta xizmatlarga ega omborlarda biz modullar o'rtasida ko'proq versiya muvofiqligini ta'minlaydigan Paketdan foydalandik.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Shunday qilib, manba kodi ustida ishlash, arxitekturani biroz o'zgartirish va omborlarni ajratish orqali biz xizmatlarimizni yanada mustaqil qilamiz.

Infratuzilma muammolari


Mikroservislarga o'tishning aksariyat salbiy tomonlari infratuzilma bilan bog'liq. Sizga avtomatlashtirilgan joylashtirish kerak bo'ladi, infratuzilmani ishga tushirish uchun sizga yangi kutubxonalar kerak bo'ladi.

Atrof muhitda qo'lda o'rnatish

Dastlab biz muhitlar uchun yechimni qo'lda o'rnatdik. Ushbu jarayonni avtomatlashtirish uchun biz CI/CD quvur liniyasini yaratdik. Biz uzluksiz yetkazib berish jarayonini tanladik, chunki uzluksiz joylashtirish biznes jarayonlari nuqtai nazaridan biz uchun hali maqbul emas. Shuning uchun operatsiyaga yuborish tugma yordamida, sinov uchun esa avtomatik ravishda amalga oshiriladi.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Biz manba kodini saqlash uchun Atlassian, Bitbucket va qurilish uchun bambukdan foydalanamiz. Biz Cake-da qurish skriptlarini yozishni yaxshi ko'ramiz, chunki u C# bilan bir xil. Tayyor paketlar Artifactory-ga keladi va Ansible avtomatik ravishda test serverlariga kiradi, shundan so'ng ularni darhol sinab ko'rish mumkin.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Alohida ro'yxatga olish


Bir vaqtlar monolitning g'oyalaridan biri umumiy daraxt kesishni ta'minlash edi. Shuningdek, disklardagi alohida jurnallar bilan nima qilish kerakligini tushunishimiz kerak edi. Bizning jurnallarimiz matnli fayllarga yoziladi. Biz standart ELK stekidan foydalanishga qaror qildik. Biz ELK ga to‘g‘ridan-to‘g‘ri provayderlar orqali yozmadik, lekin matn jurnallarini o‘zgartirishga va ulardagi kuzatuv identifikatorini identifikator sifatida yozishga, xizmat nomini qo‘shishga qaror qildik, shunda bu jurnallar keyinchalik tahlil qilinadi.

Monolitdan mikroservislarga o'tish: tarix va amaliyot

Filebeat yordamida biz jurnallarimizni quyidagi manzildan to'plashimiz mumkin serverlar, keyin ularni o'zgartiring, Kibana yordamida foydalanuvchi interfeysida so'rovlar yarating va qo'ng'iroq xizmatlar o'rtasida qanday yo'naltirilganligini ko'ring. Trace IDlari buning uchun juda foydali.

Tegishli xizmatlarni sinovdan o'tkazish va tuzatish


Dastlab biz ishlab chiqilayotgan xizmatlarni disk raskadrovka qilishni to'liq tushunmadik. Monolit bilan hamma narsa oddiy edi, biz uni mahalliy mashinada ishlatdik. Avvaliga ular mikroservislar bilan ham shunday qilishga harakat qilishdi, lekin ba'zida bitta mikroservisni to'liq ishga tushirish uchun yana bir nechtasini ishga tushirish kerak bo'ladi va bu noqulay. Biz mahalliy mashinada faqat disk raskadrovka qilmoqchi bo'lgan xizmat yoki xizmatlarni qoldiradigan modelga o'tishimiz kerakligini tushundik. Qolgan xizmatlar prod bilan konfiguratsiyaga mos keladigan serverlardan foydalaniladi. Nosozliklarni tuzatishdan so'ng, test paytida, har bir vazifa uchun faqat o'zgartirilgan xizmatlar test serveriga beriladi. Shunday qilib, eritma kelajakda ishlab chiqarishda paydo bo'ladigan shaklda sinovdan o'tkaziladi.

Faqat xizmatlarning ishlab chiqarish versiyalarini ishga tushiradigan serverlar mavjud. Ushbu serverlar voqea sodir bo'lgan taqdirda, joylashtirishdan oldin etkazib berishni tekshirish va ichki treninglar uchun kerak.

Biz mashhur Specflow kutubxonasidan foydalangan holda avtomatlashtirilgan sinov jarayonini qo'shdik. Sinovlar Ansible-dan o'rnatilgandan so'ng darhol NUnit yordamida avtomatik ravishda ishlaydi. Agar vazifani qamrab olish to'liq avtomatik bo'lsa, unda qo'lda test o'tkazishga hojat yo'q. Garchi ba'zida qo'shimcha qo'lda test hali ham talab qilinadi. Muayyan muammo uchun qaysi testlarni bajarish kerakligini aniqlash uchun Jira'da teglardan foydalanamiz.

Bundan tashqari, yukni sinovdan o'tkazish zarurati ortdi, ilgari u kamdan-kam hollarda amalga oshirilgan. Sinovlarni o'tkazish uchun JMeter, ularni saqlash uchun InfluxDB va jarayon grafiklarini yaratish uchun Grafana'dan foydalanamiz.

Biz nimaga erishdik?


Birinchidan, biz "ozod qilish" tushunchasidan xalos bo'ldik. Ikki oylik dahshatli relizlar o'tib ketdi, bu kolossus ishlab chiqarish muhitida joylashtirildi va biznes jarayonlarini vaqtincha buzdi. Endi biz xizmatlarni o'rtacha har 1,5 kunda joylashtiramiz, ularni guruhlashtiramiz, chunki ular tasdiqlangandan keyin ishga tushadi.

Bizning tizimimizda halokatli nosozliklar yo'q. Agar biz mikroservisni xato bilan chiqarsak, u bilan bog'liq funksionallik buziladi va boshqa barcha funktsiyalarga ta'sir qilmaydi. Bu foydalanuvchi tajribasini sezilarli darajada yaxshilaydi.

Biz tarqatish naqshini boshqarishimiz mumkin. Agar kerak bo'lsa, xizmatlar guruhlarini yechimning qolgan qismidan alohida tanlashingiz mumkin.

Bundan tashqari, biz yaxshilanishlarning katta navbati bilan muammoni sezilarli darajada kamaytirdik. Endi bizda ba'zi xizmatlar bilan mustaqil ishlaydigan alohida mahsulot guruhlari mavjud. Scrum jarayoni allaqachon bu erda yaxshi mos keladi. Muayyan jamoada unga vazifalarni belgilaydigan alohida mahsulot egasi bo'lishi mumkin.

Xulosa

  • Mikroservislar murakkab tizimlarni parchalash uchun juda mos keladi. Bu jarayonda biz tizimimizda nima borligini, qanday cheklangan kontekstlar borligini, ularning chegaralari qayerda joylashganligini tushuna boshlaymiz. Bu modullar o'rtasida yaxshilanishlarni to'g'ri taqsimlash va kod chalkashliklarini oldini olish imkonini beradi.
  • Mikroservislar tashkiliy foyda keltiradi. Ular ko'pincha faqat arxitektura sifatida tilga olinadi, ammo har qanday arxitektura biznes ehtiyojlarini hal qilish uchun kerak, va o'z-o'zidan emas. Shuning uchun, Scrum hozir juda mashhur bo'lganligini hisobga olsak, mikroservislar kichik jamoalardagi muammolarni hal qilish uchun juda mos keladi, deb aytishimiz mumkin.
  • Ajratish iterativ jarayondir. Siz dasturni qabul qila olmaysiz va uni oddiygina mikroservislarga bo'lasiz. Olingan mahsulotning funktsional bo'lishi dargumon. Mikroservislarni bag'ishlashda mavjud merosni qayta yozish, ya'ni uni bizga yoqadigan va funksionallik va tezlik nuqtai nazaridan biznes ehtiyojlariga yaxshiroq javob beradigan kodga aylantirish foydali bo'ladi.

    Kichik ogohlantirish: Mikroservislarga o'tish xarajatlari juda katta. Infratuzilma muammosini bir o‘zi hal qilish uchun uzoq vaqt kerak bo‘ldi. Shunday qilib, agar sizda maxsus masshtabni talab qilmaydigan kichik ilovangiz bo'lsa, jamoangizning e'tibori va vaqti uchun raqobatlashadigan mijozlar soni ko'p bo'lmasa, mikroservislar bugungi kunda sizga kerak bo'lgan narsa bo'lmasligi mumkin. Bu ancha qimmat. Agar siz jarayonni mikroservislar bilan boshlasangiz, unda monolitni ishlab chiqish bilan bir xil loyihani boshlaganingizdan ko'ra dastlab xarajatlar yuqori bo'ladi.

    PS Ko'proq hissiy hikoya (va go'yo siz uchun) - ko'ra aloqa.
    Bu yerda hisobotning to‘liq versiyasi.

Manba: www.habr.com

DDoS himoyasi, VPS VDS serverlari bo'lgan saytlar uchun ishonchli hosting sotib oling 🔥 DDoS himoyasi, VPS VDS serverlari bilan ishonchli veb-sayt xostingini sotib oling | ProHoster