# Monolitni tizimni qulatmasdan ko‘chirish

> Monolitni umuman ko‘chirish kerakmi, shuni qanday hal qilish va uni relizlar to‘xtamasdan, ma’lumotlar butun qolgan holda qismma-qism qanday ko‘chirish.

Ilya Ismatov · CTO · 24-avgust, 2026 · Loyihani qutqarish

Bitmason: https://bitmason.dev/uz/blog/migrating-a-monolith/

Monolit muvaffaqiyatsizlik emas. Muvaffaqiyatli mahsulotlarning aksariyati monolit sifatida boshlanadi, chunki bitta ma’lumotlar bazasiga ega bitta kod bazasi mijozlar nimani xohlashini bilib olishning eng tez yo‘li. Muammo keyinroq boshlanadi: relizlar sekinlashadi, billingdagi o‘zgarish qidiruvni buzadi va buyurtmalar moduliga hech kim tegishni istamaydi. Shu paytda kimdir migratsiyani taklif qiladi va xavf shundaki, davo kasallikning o‘zidan ko‘proq zarar keltirishi mumkin.

Bu maqolada migratsiya qilish-qilmaslikni qanday hal qilish, qayerdan kesishni qanday topish va jonli tizimni unga tayanadigan biznesni to‘xtatmasdan qismma-qism qanday ko‘chirish haqida so‘z boradi.

## Migratsiya kerakmi, shuni hal qiling

Arxitekturadan emas, muammodan boshlang. “Bizga mikroservislar kerak” degani yechim. Muammo esa odatda quyidagilardan biri bo‘ladi:

- Relizlar sekin yoki xavfli, chunki har bir o‘zgarish hamma narsaga tegadi.
- Tizimning bir qismi qolganidan butunlay boshqacha masshtablanishi kerak.
- Jamoalar bir-birini to‘sib qo‘yadi, chunki hammasi bitta kodda ishlaydi.
- Stekning bir qismi endi qo‘llab-quvvatlanmaydi va uni joyida yangilab bo‘lmaydi.

Muammoni yozib qo‘ying va uni tuzatishning eng arzon yo‘li qaysi ekanini so‘rang. Sekin relizlar ko‘pincha arxitektura emas, yig‘ish konveyeri (build pipeline) va testlar muammosi. Bitta qizib ketgan endpointni ko‘pincha kesh, navbat yoki o‘qish uchun replika bilan masshtablash mumkin. Eskirgan freymvorkni ba’zan o‘sha kod bazasi ichida modulma-modul yangilasa bo‘ladi.

Arzon yechimlar sinab ko‘rilgan bo‘lsa yoki ular yetarli bo‘lmasligi aniq bo‘lsa, migratsiya o‘zini oqlaydi. Shunda ham uning muhandis bo‘lmagan odam tekshira oladigan aniq maqsadi bo‘lishi kerak: “yangi arxitekturaga o‘tdik” emas, masalan, “buyurtmani rasmiylashtirish qismini to‘liq regression sinovisiz chiqara olamiz”.

## Kesishdan oldin choklarni toping

Chok bu tizimni eng kam bezovtalik bilan ajratish mumkin bo‘lgan joy. Yaxshi choklar papkalar tuzilishiga emas, biznesga ergashadi. Quyidagi qismlarni qidiring:

- O‘z lug‘atiga ega. Agar ombor jamoasi “jo‘natma”, savdo jamoasi esa “buyurtma” deb bir-biriga bog‘liq, lekin turli narsalarni atasa, shu farq chegara bo‘ladi.
- O‘z sabablariga ko‘ra o‘zgaradi. Doim birga tahrirlanadigan kod birga turishi kerak. Boshqa ritmda o‘zgaradigan kod ko‘chirishga nomzod.
- Tizimning qolgan qismi bilan o‘nlab umumiy jadvallar orqali emas, bir nechta aniq chaqiruvlar orqali bog‘lanadi.

Bunda versiyalar tarixi yordam beradi. Bir xil commitlarda birga o‘zgaradigan fayllar haqiqiy bog‘liqlikni ko‘rsatadi va u ko‘pincha rejalashtirilgan dizayndan farq qiladi. Birinchi qismni tanlashdan oldin topgan bog‘liqliklaringizni, jumladan ma’lumotlar bazasidagilarini ham chizib chiqing.

Birinchi ko‘chiriladigan qism ahamiyatga ega bo‘lishi uchun yetarlicha qimmatli, lekin oxiriga yetkazish uchun yetarlicha kichik bo‘lishi kerak. Bildirishnomalar, hisobotlar, qidiruv va fayllar bilan ishlash ko‘pincha birinchi nomzodlar bo‘ladi, chunki ular chekkada joylashgan. Asosiy domen, ya’ni mahsulotni aynan shu mahsulot qiladigan qism, odatda keyinroq, jamoa kamroq muhim narsada mashq qilib olgach ko‘chiriladi.

## Eski tizimni marshrutma-marshrut siqib chiqaring

Eng xavfsiz umumiy yondashuv “bo‘g‘uvchi anjir” (strangler fig) patterni. Martin Fowler uni mezbon daraxt atrofida o‘sadigan o‘simlik nomi bilan atagan. Siz monolitni qayta yozmaysiz. Uning oldiga nimadir qo‘yasiz va trafikni undan qismma-qism olib ketasiz.

Amalda bu quyidagicha kechadi:

1. Monolit oldiga marshrutlash qatlamini qo‘ying. Bu teskari proksi (reverse proxy), API shlyuz yoki ilovaning o‘zidagi yupqa fasad bo‘lishi mumkin.
2. Shu qatlam ortida bitta imkoniyatning yangi versiyasini yarating.
3. Trafikning kichik ulushini yoki bitta foydalanuvchilar guruhini yangi versiyaga yuboring va natijalarni eskisi bilan solishtiring.
4. Eski kod yo‘liga hech narsa kelmay qolguncha ulushni oshiring, so‘ng uni o‘chirib tashlang.

Oxirgi qadam eng muhimi. Eski kodni o‘chirmasdan yangi kod qo‘shadigan migratsiya sizga yuritish kerak bo‘lgan ikkita tizim qoldiradi. Har bir bo‘lak eski yo‘l olib tashlanishi va marshrutlash qoidasi soddalashishi bilan tugashi kerak.

Yangi va eski versiyalar bir xil ishlashi kerak bo‘lgan joyda ularni bir muddat yonma-yon yurgizing. Har bir so‘rovni ikkalasiga yuboring, foydalanuvchiga eski javobni qaytaring va har qanday farqni logga yozing. Bu soya davri har bir eski tizimda bo‘ladigan hujjatlashtirilmagan xatti-harakatlarni topadi.

## Ma’lumotlarga kim egalik qilishini hal qiling

Kod oson qismi. Ko‘p migratsiyalar umumiy ma’lumotlar bazasida to‘xtab qoladi. Agar yangi komponent ham, monolit ham bir xil jadvallarni o‘qib-yozsa, siz hech narsani ajratmagansiz: endi hech kim o‘zgartira olmaydigan sxemaga ikkinchi yozuvchini qo‘shgansiz, xolos.

Intilish kerak bo‘lgan qoida shu: har bir ma’lumot bo‘lagining bitta egasi bor. Uni faqat egasi yozadi. Boshqalar egasidan API orqali yoki u e’lon qiladigan hodisalarni tinglash orqali so‘raydi.

Bunga asta-sekin erishiladi:

- **Kim nimani yozishini xaritaga tushiring.** Har bir jadvalni va unga yozadigan har bir kod qismini ro‘yxatga oling. Ko‘p joydan yoziladigan jadvallar tashvishlanishga arziydi.
- **Avval yozuvlarni bitta joy orqali o‘tkazing.** Ma’lumotlarni ko‘chirishdan oldin monolitning o‘zi har bir jadvalga bitta modul orqali yozadigan qiling. Ko‘pincha shuning o‘zi bog‘liqlikning yarmini yo‘qotadi.
- **Avval nusxalang, keyin almashtiring.** Yangi komponentga o‘z omborini bering, uni eskisi bilan sinxron ushlang (change data capture yoki ikki joyga yozib, natijalarni solishtirish orqali) va yozuvlardan oldin o‘qishlarni yangisiga o‘tkazing.
- **Nusxalar mosligini tekshiring.** Eski va yangi ma’lumotlarni solishtirib, farqlarni ko‘rsatadigan fon vazifasini ishga tushiring. U bir muddat hech qanday farq ko‘rsatmay turmaguncha to‘liq o‘tmang.

Hisobotlar va analitika ko‘pincha hamma joydan o‘qiydi. Ularga hodisalar yoki replikatsiya orqali to‘ldiriladigan o‘z o‘qish modelini bering, shunda ular eski sxemani saqlab qolish uchun sabab bo‘lmay qoladi.

## Relizlarni davom ettiring va siljishni o‘lchang

Funksiyalar ustidagi ishni to‘xtatadigan migratsiya bir necha oy ichida biznesning qo‘llab-quvvatlashini yo‘qotadi. Butun jarayon davomida relizlarni davom ettiring. Feature flaglar ko‘chirilgan kodni yashirin holda chiqarib, tayyor bo‘lganda yoqish imkonini beradi. Qisqa umrli branchlar va kichik pull requestlar eski va yangi kodning bir-biridan uzoqlashib ketishiga yo‘l qo‘ymaydi.

Bir nechta odat jamoani o‘zini aldashdan saqlaydi:

- Kuchni migratsiya va funksiyalar o‘rtasida taxminan qanday taqsimlashni kelishib oling va uni har bir rejalashtirish yig‘ilishida ko‘rib chiqing.
- Ko‘chirilayotgan qismdagi yangi funksiyalar eski kodga emas, yangi kodga yoziladi.
- Har bir bo‘lakning haqiqatan sinab ko‘rilgan orqaga qaytarish (rollback) yo‘li bor.

Taraqqiyotni belgilangan maqsad nuqtai nazaridan o‘lchang. Foydali o‘lchovlar: yangi kod xizmat ko‘rsatayotgan trafik ulushi, bitta egasi bor jadvallar soni, merge qilishdan productiongacha ketadigan vaqt va relizni qanchalik tez-tez orqaga qaytarishga to‘g‘ri kelishi. Yaratilgan servislar soni taraqqiyot o‘lchovi emas: hamma narsa yomonlashayotgan paytda ham u o‘sishi mumkin.

## Modulli monolit qachon to‘g‘ri javob

Ko‘p jamoalar yarim yo‘lda o‘zlariga tarmoq chaqiruvlari emas, chegaralar kerak bo‘lganini anglaydi. Modulli monolit bitta deploy qilinadigan ilova va bitta ma’lumotlar bazasi serverini saqlaydi, lekin kodni aniq ochiq interfeyslari va yopiq ichki qismlariga ega modullarga bo‘ladi. Har bir modul o‘z jadvallariga egalik qiladi, boshqa modullar esa ularga kira olmaydi.

Bu odamlar servislardan kutadigan afzalliklarning ko‘pini beradi: aniq egalik, qismlarga bo‘lib tushunsa bo‘ladigan kod va keyinroq modulni ajratib chiqarish imkoniyati. Shu bilan birga ularning xarajatlaridan qochadi: komponentlar orasidagi tarmoq nosozliklari, taqsimlangan tranzaksiyalar, operatsion yukning ortishi va so‘rovni ko‘plab jarayonlar bo‘ylab kuzatish.

Modulli monolit odatda jamoa bitta xonada kelisha oladigan darajada kichik bo‘lsa, qismlar o‘xshash tarzda masshtablansa va asl og‘riq yuk emas, chigal kod bo‘lsa, yaxshiroq javobdir. Chegaralarni yaxshi niyatga emas, vositalarga (CIda tekshiriladigan bog‘liqlik qoidalariga) tayanib ushlang, aks holda ular bir necha reliz ichida yemiriladi.

Modulni alohida servisga faqat sababini ayta olsangiz ajratib chiqaring: u mustaqil masshtablanishi kerak, unga boshqa reliz ritmi kerak yoki uni boshidan oxirigacha alohida jamoa boshqarishi kerak.

## Qayerdan boshlash kerak

Migratsiya qaysi muammoni hal qilishi kerakligini va u hal bo‘lganini qanday bilishingizni yozib qo‘ying. Haqiqiy bog‘liqlikni kodda ham, ma’lumotlar bazasida ham xaritaga tushiring. Chekkadagi bitta imkoniyatni tanlang, monolit oldiga marshrutlash qatlamini qo‘ying, shu imkoniyatni ko‘chiring va eski yo‘lni o‘chirib tashlang. So‘ng keyingi bo‘lakni o‘rganganlaringiz asosida tanlang.

Shu tarzda qilingan migratsiyada hamma narsa birdaniga o‘zgaradigan katta kun hech qachon bo‘lmaydi. Bu kichik, ortga qaytarsa bo‘ladigan qadamlar ketma-ketligi va ularning har biri tizimni avvalgidan biroz osonroq o‘zgartiriladigan holatda qoldiradi.

## Maqola bo‘yicha savollar

### Monolit migratsiyasi odatda qancha davom etadi?

Birinchi bahodan uzoqroq, chunki eng qiyin qismlar ma’lumotlarni ko‘chirishni boshlagandagina ko‘rinadi. Ishni har biri o‘z-o‘zicha nimadir beradigan bo‘laklarga bo‘lib rejalashtiring, shunda ish istalgan nuqtada to‘xtasa ham, qilingan mehnat o‘zini oqlagan bo‘ladi.

### Migratsiya davomida yangi funksiyalarni to‘xtatib qo‘yish kerakmi?

Kamdan-kam hollarda. Uzoq muzlatish biznesga migratsiya tejaydiganidan qimmatroqqa tushadi. Jamoaning barqaror bir qismini funksiyalarda qoldiring, ko‘chirilgan qismlardagi yangi ishlarni esa yangi kodga yo‘naltiring.

### To‘liq testlar to‘plamisiz migratsiya qilsa bo‘ladimi?

Ha, lekin har bir qismni ko‘chirishdan oldin uning atrofida xarakterlovchi testlar (characterisation tests) yozing. Ular eski kod bugun nima qilayotganini qayd etadi, shunda yangi kod ham aynan shuni qilishini isbotlay olasiz.

### Migratsiya oxirida mikroservislar bo‘lishi shartmi?

Yo‘q. Maqsad jamoangiz xavfsiz o‘zgartira oladigan tizim. Ko‘p mahsulotlar uchun bu servislar to‘dasi emas, chegaralari aniq modulli monolitdir.

