Monolith — dasturiy tizimning asosiy qismlari bitta deployment birligi sifatida yaratiladigan va ishga tushiriladigan arxitektura. Bunday tizimda UI, business logic, data access va boshqa modullar bir codebase yoki bitta executable ichida bo‘lishi mumkin.
Monolith atamasi “tuzilmasiz katta kod” degani emas. Yaxshi monolith ichki modullar, qatlamlar va aniq boundarylarga ega bo‘lishi mumkin.
Deployment birligi
Monolithning eng muhim belgisi — tizim odatda bir butun sifatida deploy qilinadi.
Masalan:
application.war
application.jar
django-app container
single executable
Kodning kichik qismi o‘zgarsa ham yangi application artifacti build va deploy qilinadi.
Ichki tuzilma
Monolith quyidagi modullarga bo‘linishi mumkin:
Application
├── Users
├── Orders
├── Payments
├── Notifications
└── Reports
Modullar bir process ichida function call yoki method orqali ishlaydi.
Bu network chaqiruviga qaraganda sodda va tez.
Layered monolith
Keng tarqalgan qatlamlar:
Dependency yo‘nalishi aniq saqlansa codebase katta bo‘lsa ham tushunarli qoladi.
Modular monolith
Modular monolith — bitta deployment ichida aniq ajratilgan modullarga ega monolith.
Har module:
- o‘z public API;
- ichki implementation;
- data ownership;
- test;
- dependency qoidasi
ga ega.
Boshqa module ichki class yoki tablega to‘g‘ridan-to‘g‘ri kirmaydi.
Bu keyinchalik ayrim modulni alohida service’ga ajratishni osonlashtiradi.
Monolith afzalliklari
Sodda deployment
Bitta artifact va bitta asosiy application lifecycle.
Lokal transaction
Bir database transaction ichida bir nechta business operation bajarish oson.
Tez ichki chaqiriq
Modulelar orasida network serialization va timeout yo‘q.
Debugging
Bitta process stack trace va lokal development muhiti ko‘pincha soddaroq.
Test
End-to-end jarayonni bitta application instance’da ishga tushirish mumkin.
Boshlang‘ich tezlik
Kichik jamoa yangi mahsulotni tez yaratishi mumkin.
Monolith cheklovlari
Mustaqil deploy yo‘q
Bitta module o‘zgarishi butun application release’ini talab qiladi.
Scale
Faqat bitta qism ko‘p resource talab qilsa ham butun application instance ko‘paytirilishi mumkin.
Coupling
Boundarylar nazorat qilinmasa modulelar bir-birining ichki qismlariga qattiq bog‘lanadi.
Build va startup
Codebase kattalashganda build, test va startup sekinlashishi mumkin.
Texnologiya tanlovi
Barcha modullar odatda bir xil runtime va asosiy stackdan foydalanadi.
Shared database
Monolith ko‘pincha bitta database’dan foydalanadi.
Bu transactionni soddalashtiradi.
Biroq barcha module istalgan tablega kira olsa data ownership yo‘qoladi.
Modular monolithda har module o‘z schema yoki repository qatlami orqali ishlashi mumkin.
Process isolation
Bitta process ichidagi xato butun applicationga ta’sir qilishi mumkin.
Masalan:
- memory leak;
- deadlock;
- process crash;
- CPUni band qiluvchi task;
- global state.
Resource limit va background workerni alohida processga ajratish mumkin, lekin asosiy tizim monolith bo‘lib qolishi mumkin.
Monolith va microservice
| Jihat | Monolith | Microservice |
|---|---|---|
| Deployment | Bitta asosiy birlik | Ko‘p mustaqil service |
| Aloqa | Lokal function call | Network |
| Transaction | Lokal osonroq | Distributed murakkab |
| Operatsion yuk | Kamroq | Yuqoriroq |
| Scale | Ko‘pincha butun application | Service bo‘yicha |
| Debugging | Bir processda | Distributed tracing kerak |
Microservice har doim monolithdan yaxshi emas.
Distributed monolith
Tizim ko‘p service’ga bo‘lingan, ammo ular:
- birga deploy;
- bir xil database;
- qat’iy sinxron chaqiriq;
- mustaqil o‘zgara olmaydi
holatida bo‘lsa distributed monolith deb ataladi.
Bu microservice murakkabligini olib kelib, mustaqillik afzalligini bermaydi.
Team ownership
Monolithda ko‘p jamoa bitta repository va release pipeline bilan ishlashi mumkin.
Aniq module ownership, code owner va dependency qoidalari bo‘lmasa merge conflict va koordinatsiya oshadi.
Monorepo vositalari faqat ta’sirlangan module testlarini ishga tushirishi mumkin.
Refactoring
Katta monolithni yaxshilash yo‘llari:
- module boundary aniqlash;
- cycle’larni yo‘qotish;
- shared utilityni kamaytirish;
- domain bo‘yicha ajratish;
- internal API;
- database ownership;
- background jobni ajratish;
- testlarni qatlamlash.
Darhol microservice’ga bo‘lish shart emas.
Service’ga ajratish
Ayrim modul quyidagi holatlarda alohida service’ga ajratilishi mumkin:
- mustaqil scale;
- alohida security boundary;
- boshqa release tezligi;
- boshqa runtime talabi;
- aniq domain boundary;
- mustaqil jamoa.
Ajratishdan oldin monolith ichida boundary shakllantiriladi.
Observability
Monolith ham:
- structured log;
- metric;
- trace;
- health check;
- profiler;
- error tracking
talab qiladi.
Bitta process bo‘lishi observability kerak emas degani emas.
Code ownership
Modular monolithda har business module uchun mas’ul jamoa va public entry point belgilanadi. Dependency checker bir modulning boshqa modul internal package’iga import qilishini bloklashi mumkin.
Database migration
Bitta application va database bo‘lsa migration markaziy pipeline orqali bajariladi. Rolling deployment mavjud bo‘lsa eski va yangi application versiyasi bir muddat bir schema bilan ishlaydi. Columnni darhol rename qilish o‘rniga add, migrate va remove bosqichlari qo‘llanadi.
Background task
Web requestdan tashqari queue consumer, scheduler va workerlar bitta repositorydan chiqishi mumkin. Ular alohida process sifatida deploy qilinsa ham bir xil domain model va release’ga bog‘liq bo‘lishi mumkin.
Monolith testi
Module testlari tez va izolyatsiyalangan, application-level testlar esa modullar integratsiyasini tekshiradi. Har o‘zgarishda barcha end-to-end testlarni ishlatishdan ko‘ra ta’sirlangan module graphidan foydalanish build vaqtini kamaytiradi.
Bog‘liq tushunchalar
Monolithic architecture, Modular monolith, Layered architecture, Microservice, Deployment unit, Shared database, Coupling, Distributed monolith, Module