IlmHamroh
Python kursi/Arxitektura9/12-dars19 daqiqa
Mundarija (22)

27.9-dars: Monolit va mikroservis

27-QISM — ARXITEKTURA · 9-dars


1. Kirish va motivatsiya

Tizimni qurishning ikki asosiy yo'li bor: hamma narsani bitta dastur ga jamlash (monolit) yoki ko'p mustaqil xizmat ga bo'lish (mikroservis). Ko'plar "mikroservis zamonaviy, monolit eskirgan" deb o'ylaydi va darrov mikroservisdan boshlaydi — lekin bu ko'pincha xato: kichik jamoa ko'p xizmatni boshqara olmaydi (murakkablik, tarmoq, deploy). Aksincha, ba'zi katta tizimlar monolit sifatida qotib qoladi (o'zgartirish imkonsiz). Monolit va mikroservis — ikki arxitektura uslubi, har biri o'z o'rniga ega. To'g'ri tanlov — texnik moda emas, balki jamoa, hajm va ehtiyojga bog'liq.

Monolit — butun tizim bitta ilova sifatida (bir kod bazasi, bir jarayon, bir deploy): barcha modullar birga ishlaydi, funksiya chaqiruvlari bilan aloqa. Mikroservis — tizim ko'p mustaqil xizmat ga bo'linadi (har biri o'z kod bazasi, jarayoni, bazasi), tarmoq (HTTP, xabar) orqali aloqa. Monolit — sodda boshlash (bir joy), lekin katta bo'lganda qotadi. Mikroservis — mustaqil miqyoslash va deploy, lekin taqsimlangan tizim murakkabligi (tarmoq, izchillik, kuzatuv). Bu bounded context 27.8-bob bilan bog'liq (xizmat = kontekst). Tanlov — muvozanat (sodda vs mustaqillik).

Real vaziyat. Bir startap mikroservisdan boshladi (moda deb) — 5 kishilik jamoa 12 xizmatni boshqarardi: har o'zgarish bir necha xizmatga tegardi, deploy murakkab, xatolarni topish qiyin (qaysi xizmat?). Ular monolit ga qaytdi (bir ilova) — rivojlanish tezlashdi, deploy oddiy bo'ldi. Keyinroq, tizim va jamoa o'sganda, ayrim qismlarni (to'lov, xabarnoma) alohida xizmatga ajratdilar (kerak bo'lganda). To'g'ri yo'l — monolitdan boshlash, kerak bo'lganda bo'lish.

Bu darsda monolit va mikroservis arxitekturalarini o'rganamiz.

Bu darsda:

  • Monolit nima
  • Mikroservis nima
  • Monolit afzalligi va kamchiligi
  • Mikroservis afzalligi va kamchiligi
  • Taqsimlangan tizim murakkabligi
  • Qaysi birini tanlash
  • Modulli monolit (o'rta yo'l)
  • Amaliy: xizmatlar aloqasi

ℹ Misollar sof Python bilan monolit/xizmat aloqasini ko'rsatadi (tarmoq mock — deterministik).


2. Nazariya — chuqur tushuntirish

2.1. Monolit nima

Butun tizim bitta ilova:

┌─────────────────────────┐
│      MONOLIT            │
│  Foydalanuvchi | Buyurtma│  bir kod bazasi
│  To'lov | Xabar          │  bir jarayon
│  (bir baza)              │  bir deploy
└─────────────────────────┘
   modullar funksiya chaqiruvi bilan

Monolit — butun tizim bitta ilova sifatida: bir kod bazasi, bir jarayon (process), bir deploy, odatda bir baza. Barcha modullar (foydalanuvchi, buyurtma, to'lov) birga, o'zaro funksiya chaqiruvi bilan aloqa (tarmoq emas). Sabab: sodda (bir loyiha, bir deploy — boshlash oson), tez (funksiya chaqiruvi — tarmoqsiz), izchil (bir baza — tranzaksiya oson), oson sinash (bir joy). Kamchilik keyin (katta bo'lganda). Monolit — birlashgan tizim (bir butun). Boshlash uchun eng sodda.

2.2. Mikroservis nima

Ko'p mustaqil xizmat:

┌──────────┐  ┌──────────┐  ┌──────────┐
│Foydalanuv│  │Buyurtma  │  │To'lov    │
│ (baza 1) │  │ (baza 2) │  │ (baza 3) │
└────┬─────┘  └────┬─────┘  └────┬─────┘
     └──── tarmoq (HTTP/xabar) ──┘
   har xizmat mustaqil (deploy, miqyos)

Mikroservis — tizim ko'p mustaqil xizmat ga bo'linadi, har biri: o'z kod bazasi, o'z jarayoni, o'z bazasi, mustaqil deploy. Xizmatlar tarmoq orqali aloqa (HTTP/REST, gRPC, xabar navbati). Har xizmat bir biznes imkoniyatini qamraydi (bounded context — 27.8). Sabab: mustaqil miqyoslash (faqat yuklangan xizmatni ko'paytirish), mustaqil deploy (bir xizmatni yangilash — boshqasi tegilmaydi), texnologiya erkinligi (har xizmat o'z tili), jamoa mustaqilligi. Narx: taqsimlangan tizim murakkabligi. Mikroservis — mustaqil xizmatlar to'plami.

2.3. Monolit afzalligi va kamchiligi

Afzallik Kamchilik
Sodda (bir loyiha) Katta bo'lganda qotadi
Tez (funksiya chaqiruvi) Bir deploy (hammasi birga)
Izchil (bir baza, tranzaksiya) Miqyoslash — hammasi
Oson sinash/debug Texnologiya qulfi (bir stek)

Monolit afzalliklari: sodda (bir kod bazasi, deploy, kuzatuv), tez (funksiya chaqiruvi — tarmoq kechikishi yo'q), izchil (bir baza — ACID tranzaksiya oson — 23-qism), oson rivojlanish (kichik/o'rta loyihada). Kamchiliklari: katta bo'lganda qotadi (kod chalkashadi, o'zgartirish qiyin), bir deploy (kichik o'zgarish — butun tizimni deploy), miqyoslash — butun ilova (bir modul yuklangan bo'lsa ham hammasini ko'paytirish), texnologiya qulfi (bir stek). Monolit — kichik/o'rta uchun ideal, juda katta uchun qiyin. Sodda, lekin o'sish cheklovi.

2.4. Mikroservis afzalligi va kamchiligi

Afzallik Kamchilik
Mustaqil deploy Taqsimlangan murakkablik
Mustaqil miqyos Tarmoq (kechikish, xato)
Texnologiya erkinligi Izchillik qiyin (ko'p baza)
Jamoa mustaqilligi Kuzatuv, debug murakkab

Mikroservis afzalliklari: mustaqil deploy (bir xizmat yangilanadi — qolganlar tegilmaydi), mustaqil miqyoslash (faqat yuklangan xizmat), texnologiya erkinligi (har xizmat o'z tili/bazasi), jamoa mustaqilligi (har jamoa o'z xizmatiga egalik). Kamchiliklari: taqsimlangan tizim murakkabligi (tarmoq — kechikish, xato; xizmatlararo izchillik — ko'p baza, tranzaksiya qiyin; kuzatuv — so'rov ko'p xizmatdan o'tadi; deploy/infratuzilma — Docker, Kubernetes — 28-qism). Mikroservis — katta jamoa/tizim uchun, kichik uchun ortiqcha. Kuchli, lekin murakkab.

2.5. Taqsimlangan tizim murakkabligi

Mikroservis — taqsimlangan tizim (distributed system), bu tub murakkablik keltiradi: tarmoq ishonchsiz (so'rov yo'qoladi, kechikadi — qayta urinish, timeout kerak); izchillik qiyin (ko'p baza — bir tranzaksiya emas; "eventual consistency" — oxir-oqibat izchil, darhol emas); taqsimlangan xato (bir xizmat yiqilsa — zanjir; "circuit breaker" — 27.12); kuzatuv (bir so'rov ko'p xizmatdan o'tadi — distributed tracing kerak); versiyalash (xizmat interfeysi o'zgarsa — mos kelish). Bu "monolitda bepul" narsalar (bir tranzaksiya, bir log) mikroservisda ish talab qiladi. Taqsimlangan murakkablik — mikroservisning haqiqiy narxi. Tarmoq — yangi muammolar manbai.

2.6. Qaysi birini tanlash

Tanlov jamoa, hajm, ehtiyojga bog'liq: Monolit tanlang — kichik/o'rta jamoa, yangi loyiha (domen noaniq), oddiy/o'rta murakkablik, tez boshlash kerak; Mikroservis tanlang — katta jamoa (ko'p mustaqil guruh), juda katta tizim, qismlar turlicha miqyoslanadi, mustaqil deploy zarur. Muhim qoida: monolitdan boshlang (Martin Fowler — "monolith first"): domen aniqlanmaguncha bo'lish (chegaralarni bilmasdan) — noto'g'ri bo'linish (keyin tuzatish qiyin); tizim va jamoa o'sganda, kerakli qismni ajrating. Mikroservis — yechim, lekin muammosiz emas. Tanlov — moda emas, ehtiyoj. Boshlash sodda — o'sganda bo'l.

2.7. Modulli monolit (o'rta yo'l)

Modulli monolit (modular monolith) — o'rta yo'l: bitta ilova (monolit — sodda deploy), lekin ichida aniq modullar (mustaqil, chegarali — mikroservis intizomi). Har modul o'z domeni (bounded context — 27.8), aniq interfeys bilan aloqa (to'g'ridan boshqa modulning ichiga kirmaydi). Foyda: monolit soddaligini (bir deploy, funksiya chaqiruvi) va mikroservis tartibini (modullik, chegara) birlashtiradi; kerak bo'lganda modulni xizmatga ajratish oson (chegara tayyor). Ko'p mutaxassis buni tavsiya qiladi: modulli monolitdan boshlang, kerak bo'lsa mikroservisga o'ting. Modulli monolit — sodda, lekin tartibli (eng yaxshi boshlash).

2.8. Monolit/mikroservis — texnik emas, tashkiliy tanlov

Monolit vs mikroservis — ko'pincha texnik emas, tashkiliy tanlov: mikroservis chegaralari ko'pincha jamoa chegaralariga mos (Conway qonuni — tizim tuzilishi tashkilot muloqotini aks ettiradi). Katta tashkilot (ko'p mustaqil jamoa) — mikroservis (har jamoa o'z xizmati); kichik jamoa — monolit (bir jamoa, bir kod). Xato: kichik jamoa mikroservisni tanlashi (tashkiliy ehtiyoj yo'q, faqat texnik murakkablik). Bu bounded context (27.8 — chegaralar), qatlamlar 27.6-bob bilan bog'liq. Arxitektura tanlovi — jamoa strukturasi va o'sish rejasiga bog'liq (nafaqat texnika). Monolit/mikroservis — tashkilot va tizim muvozanati. Tanlov — jamoaga mos.


3. Tez ma'lumotnoma

python
# MONOLIT — bir ilova (funksiya chaqiruvi)
class Ilova:
    def __init__(self):
        self.buyurtma = BuyurtmaModuli()
        self.tolov = TolovModuli()
    def buyurtma_ber(self, ...):
        b = self.buyurtma.yarat(...)     # to'g'ridan chaqiruv
        self.tolov.tola(...)             # bir jarayon

# MIKROSERVIS — tarmoq orqali (HTTP/xabar)
# Buyurtma xizmati → HTTP → To'lov xizmati
# response = requests.post("http://tolov/tola", ...)
# har xizmat: o'z kodi, jarayoni, bazasi

# TANLOV:
# Monolit: kichik jamoa, yangi loyiha, sodda
# Mikroservis: katta jamoa, mustaqil deploy/miqyos
# Modulli monolit: bir ilova + aniq modullar (o'rta yo'l)
# QOIDA: monolitdan boshlang (kerak bo'lsa bo'ling)

Monolit va mikroservis xulosasi

Monolit — bir ilova (sodda, tez, izchil; katta bo'lsa qotadi)
Mikroservis — ko'p xizmat (mustaqil deploy/miqyos; tarmoq murakkab)
Taqsimlangan murakkablik — mikroservis narxi (tarmoq, izchillik)
Tanlov — jamoa/hajm/ehtiyoj (moda emas)
Monolitdan boshlang · Modulli monolit — o'rta yo'l

4. Batafsil misollar

Misollar sof Python bilan — tarmoq mock (deterministik).

Misol 1 — Monolit: modullar funksiya chaqiruvi bilan

python
"""Monolit: modullar bir ilovada, funksiya chaqiruvi bilan (tarmoqsiz)."""


class BuyurtmaModuli:
    def __init__(self) -> None:
        self.buyurtmalar: list = []

    def yarat(self, mahsulot: str, summa: float) -> dict:
        buyurtma = {"id": len(self.buyurtmalar) + 1, "mahsulot": mahsulot, "summa": summa}
        self.buyurtmalar.append(buyurtma)
        return buyurtma


class TolovModuli:
    def tola(self, summa: float) -> str:
        return f"{summa} to'landi"


class XabarModuli:
    def yubor(self, matn: str) -> str:
        return f"Xabar: {matn}"


class Ilova:
    """Monolit — barcha modul bir joyda."""

    def __init__(self) -> None:
        self.buyurtma = BuyurtmaModuli()
        self.tolov = TolovModuli()
        self.xabar = XabarModuli()

    def buyurtma_ber(self, mahsulot: str, summa: float) -> dict:
        # to'g'ridan funksiya chaqiruvi (bir jarayon)
        b = self.buyurtma.yarat(mahsulot, summa)
        tolov = self.tolov.tola(summa)
        xabar = self.xabar.yubor(f"Buyurtma {b['id']} qabul qilindi")
        return {"buyurtma": b, "tolov": tolov, "xabar": xabar}


def main() -> None:
    ilova = Ilova()

    print("=== 1. Buyurtma berish (bir oqim) ===")
    natija = ilova.buyurtma_ber("Python kursi", 1000)
    print(f"  buyurtma: {natija['buyurtma']}")
    print(f"  to'lov: {natija['tolov']}")
    print(f"  xabar: {natija['xabar']}")

    print("\n=== 2. Bir jarayon (tarmoqsiz) ===")
    print("  modullar funksiya chaqiruvi bilan")

    print("\n=== 3. Izchil (bir baza) ===")
    print(f"  jami buyurtma: {len(ilova.buyurtma.buyurtmalar)}")

    print("\n=== 4. Sodda ===")
    print("  bir kod, bir deploy, bir jarayon")
    print("  ⭐ Monolit — birlashgan (funksiya chaqiruvi)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Buyurtma berish (bir oqim) ===
  buyurtma: {'id': 1, 'mahsulot': 'Python kursi', 'summa': 1000}
  to'lov: 1000 to'landi
  xabar: Xabar: Buyurtma 1 qabul qilindi

=== 2. Bir jarayon (tarmoqsiz) ===
  modullar funksiya chaqiruvi bilan

=== 3. Izchil (bir baza) ===
  jami buyurtma: 1

=== 4. Sodda ===
  bir kod, bir deploy, bir jarayon
  ⭐ Monolit — birlashgan (funksiya chaqiruvi)

Nima ko'rsatdi: 2.1-bo'lim.

Misol 2 — Mikroservis: tarmoq orqali aloqa (mock)

python
"""Mikroservis: xizmatlar tarmoq (mock HTTP) orqali aloqa — mustaqil."""


class TolovXizmati:
    """Alohida xizmat (o'z jarayoni)."""

    def handle(self, sorov: dict) -> dict:
        summa = sorov.get("summa", 0)
        return {"holat": 200, "xabar": f"{summa} to'landi"}


class XabarXizmati:
    """Alohida xizmat."""

    def handle(self, sorov: dict) -> dict:
        return {"holat": 200, "xabar": f"Xabar: {sorov.get('matn')}"}


class MockTarmoq:
    """HTTP o'rniga (deterministik) — xizmatlarni ulaydi."""

    def __init__(self) -> None:
        self.xizmatlar: dict = {}

    def royxatga_ol(self, nom: str, xizmat) -> None:
        self.xizmatlar[nom] = xizmat

    def sorov(self, xizmat_nomi: str, malumot: dict) -> dict:
        # tarmoq chaqiruvini taqlid qiladi
        return self.xizmatlar[xizmat_nomi].handle(malumot)


class BuyurtmaXizmati:
    """Boshqa xizmatlarni tarmoq orqali chaqiradi."""

    def __init__(self, tarmoq: MockTarmoq) -> None:
        self.tarmoq = tarmoq

    def buyurtma_ber(self, mahsulot: str, summa: float) -> dict:
        # tarmoq orqali (funksiya chaqiruvi emas)
        tolov = self.tarmoq.sorov("tolov", {"summa": summa})
        xabar = self.tarmoq.sorov("xabar", {"matn": f"{mahsulot} qabul"})
        return {"mahsulot": mahsulot, "tolov": tolov, "xabar": xabar}


def main() -> None:
    tarmoq = MockTarmoq()
    tarmoq.royxatga_ol("tolov", TolovXizmati())
    tarmoq.royxatga_ol("xabar", XabarXizmati())
    buyurtma = BuyurtmaXizmati(tarmoq)

    print("=== 1. Buyurtma (xizmatlar orqali) ===")
    natija = buyurtma.buyurtma_ber("Python kursi", 1000)
    print(f"  to'lov javobi: {natija['tolov']}")
    print(f"  xabar javobi: {natija['xabar']}")

    print("\n=== 2. Har xizmat mustaqil ===")
    print(f"  ro'yxatdagi xizmatlar: {list(tarmoq.xizmatlar)}")

    print("\n=== 3. Tarmoq orqali aloqa ===")
    print("  BuyurtmaXizmati → tarmoq → Tolov/Xabar")
    print("  har xizmat alohida (o'z jarayoni)")

    print("\n=== 4. Mustaqillik narxi ===")
    print("  tarmoq (kechikish, xato) — monolitda yo'q edi")
    print("  ⭐ Mikroservis — tarmoq orqali (mustaqil)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Buyurtma (xizmatlar orqali) ===
  to'lov javobi: {'holat': 200, 'xabar': "1000 to'landi"}
  xabar javobi: {'holat': 200, 'xabar': 'Xabar: Python kursi qabul'}

=== 2. Har xizmat mustaqil ===
  ro'yxatdagi xizmatlar: ['tolov', 'xabar']

=== 3. Tarmoq orqali aloqa ===
  BuyurtmaXizmati → tarmoq → Tolov/Xabar
  har xizmat alohida (o'z jarayoni)

=== 4. Mustaqillik narxi ===
  tarmoq (kechikish, xato) — monolitda yo'q edi
  ⭐ Mikroservis — tarmoq orqali (mustaqil)

Nima ko'rsatdi: 2.2-bo'lim.

Misol 3 — Tarmoq xatosi (mikroservis murakkabligi)

python
"""Taqsimlangan murakkablik: tarmoq xatosi — qayta urinish kerak (monolitda yo'q)."""


class IshonchsizXizmat:
    """Xizmat ba'zan yiqiladi (tarmoq haqiqati)."""

    def __init__(self) -> None:
        self.urinishlar = 0

    def handle(self, sorov: dict) -> dict:
        self.urinishlar += 1
        # birinchi 2 urinish yiqiladi (deterministik simulyatsiya)
        if self.urinishlar < 3:
            raise ConnectionError(f"Tarmoq xatosi (urinish {self.urinishlar})")
        return {"holat": 200, "natija": "muvaffaqiyat"}


def qayta_urinish(xizmat, sorov: dict, max_urinish: int = 3) -> dict:
    """Tarmoq xatosida qayta urinish (mikroservis naqshi)."""
    for urinish in range(1, max_urinish + 1):
        try:
            return xizmat.handle(sorov)
        except ConnectionError as e:
            if urinish == max_urinish:
                return {"holat": 500, "xato": str(e)}
            # aks holda qayta urinadi
    return {"holat": 500, "xato": "noma'lum"}


def main() -> None:
    xizmat = IshonchsizXizmat()

    print("=== 1. To'g'ridan chaqiruv (yiqiladi) ===")
    try:
        IshonchsizXizmat().handle({})
    except ConnectionError as e:
        print(f"  {e}")

    print("\n=== 2. Qayta urinish bilan ===")
    natija = qayta_urinish(xizmat, {"malumot": "test"})
    print(f"  natija: {natija}")
    print(f"  jami urinish: {xizmat.urinishlar}")

    print("\n=== 3. Nega kerak ===")
    print("  tarmoq ishonchsiz (so'rov yo'qoladi)")
    print("  monolitda funksiya chaqiruvi — bunday emas")

    print("\n=== 4. Taqsimlangan murakkablik ===")
    print("  qayta urinish, timeout, circuit breaker")
    print("  monolitda 'bepul' — mikroservisda ish")
    print("  ⭐ Tarmoq — yangi muammolar (mikroservis narxi)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. To'g'ridan chaqiruv (yiqiladi) ===
  Tarmoq xatosi (urinish 1)

=== 2. Qayta urinish bilan ===
  natija: {'holat': 200, 'natija': 'muvaffaqiyat'}
  jami urinish: 3

=== 3. Nega kerak ===
  tarmoq ishonchsiz (so'rov yo'qoladi)
  monolitda funksiya chaqiruvi — bunday emas

=== 4. Taqsimlangan murakkablik ===
  qayta urinish, timeout, circuit breaker
  monolitda 'bepul' — mikroservisda ish
  ⭐ Tarmoq — yangi muammolar (mikroservis narxi)

Nima ko'rsatdi: 2.5-bo'lim.

Misol 4 — Modulli monolit (aniq modullar, bir ilova)

python
"""Modulli monolit: bir ilova, lekin aniq modullar (interfeys orqali)."""
from abc import ABC, abstractmethod


# har modul aniq interfeys (chegara) bilan
class TolovInterfeysi(ABC):
    @abstractmethod
    def tola(self, summa: float) -> str: ...


class TolovModuli(TolovInterfeysi):
    def tola(self, summa: float) -> str:
        return f"{summa} to'landi"


class BuyurtmaModuli:
    """Boshqa modul bilan interfeys orqali (to'g'ridan ichiga emas)."""

    def __init__(self, tolov: TolovInterfeysi) -> None:
        self.tolov = tolov   # interfeysga bog'liq (chegara)
        self.buyurtmalar: list = []

    def yarat(self, mahsulot: str, summa: float) -> dict:
        b = {"id": len(self.buyurtmalar) + 1, "mahsulot": mahsulot}
        self.buyurtmalar.append(b)
        tolov = self.tolov.tola(summa)   # interfeys orqali
        return {"buyurtma": b, "tolov": tolov}


def main() -> None:
    # bir ilova, lekin modullar aniq chegarali
    tolov = TolovModuli()
    buyurtma = BuyurtmaModuli(tolov)

    print("=== 1. Buyurtma (modullar interfeys orqali) ===")
    print(f"  {buyurtma.yarat('Python kursi', 1000)}")

    print("\n=== 2. Aniq chegara (interfeys) ===")
    print("  BuyurtmaModuli → TolovInterfeysi (ichiga emas)")

    print("\n=== 3. Bir ilova (sodda deploy) ===")
    print("  funksiya chaqiruvi (tarmoqsiz — monolit)")
    print("  lekin modullar mustaqil (mikroservis intizomi)")

    print("\n=== 4. Kerak bo'lsa ajratish oson ===")
    print("  chegara tayyor → modulni xizmatga ajratish oson")
    print("  monolit soddaligi + mikroservis tartibi")
    print("  ⭐ Modulli monolit — o'rta yo'l (eng yaxshi boshlash)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Buyurtma (modullar interfeys orqali) ===
  {'buyurtma': {'id': 1, 'mahsulot': 'Python kursi'}, 'tolov': "1000 to'landi"}

=== 2. Aniq chegara (interfeys) ===
  BuyurtmaModuli → TolovInterfeysi (ichiga emas)

=== 3. Bir ilova (sodda deploy) ===
  funksiya chaqiruvi (tarmoqsiz — monolit)
  lekin modullar mustaqil (mikroservis intizomi)

=== 4. Kerak bo'lsa ajratish oson ===
  chegara tayyor → modulni xizmatga ajratish oson
  monolit soddaligi + mikroservis tartibi
  ⭐ Modulli monolit — o'rta yo'l (eng yaxshi boshlash)

Nima ko'rsatdi: 2.7-bo'lim.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"Mikroservis zamonaviy, monolit eskirgan" Har biri o'z o'rniga
"Mikroservisdan boshlash" Monolitdan boshlang
"Mikroservis doim yaxshi" Taqsimlangan murakkablik
"Monolit = yomon kod" Sodda, tez, izchil
"Tarmoq funksiya chaqiruvi kabi" Ishonchsiz (xato, kechikish)
"Ko'p xizmat = tez" Aloqa, izchillik narxi
"Tanlov texnik" Tashkiliy ham (jamoa)
"Faqat ikki variant" Modulli monolit (o'rta)

6. Keng tarqalgan xatolar va yechimlari

1. Erta mikroservis (domen noaniq)

python
# yangi loyiha darrov 10 xizmat            # ⚠️
# monolitdan boshlash (chegarani bilib)     # ✅

2. Kichik jamoa, ko'p xizmat

python
# 3 kishi 15 xizmatni boshqaradi           # ⚠️
# jamoaga mos (kam xizmat yoki monolit)     # ✅

3. Tarmoqni funksiya kabi ishonish

python
natija = xizmat_chaqir()  # xato bo'lsa?    # ⚠️
try: ... except: qayta_urin()  # timeout     # ✅

4. Taqsimlangan tranzaksiya (ACID kutish)

python
# ko'p bazada bir tranzaksiya kutish        # ⚠️
# saga naqshi (eventual consistency)         # ✅

5. Xizmatlar juda mayda (nano)

python
# har funksiya alohida xizmat               # ⚠️
# bounded context bo'yicha (mazmunli)        # ✅

6. Umumiy baza (xizmatlar ulashadi)

python
# ko'p xizmat bir bazaga (bog'lanish)        # ⚠️
# har xizmat o'z bazasi (mustaqil)           # ✅

7. Kuzatuvsiz mikroservis

python
# xato qaysi xizmatda? (log yo'q)           # ⚠️
# distributed tracing, markaziy log          # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 27.8-dars (o'tilgan): DDD — bounded context = xizmat
  • 27.10-dars: Hodisaga asoslangan — xizmatlar aloqasi
  • 28-qism: Docker, Kubernetes — mikroservis deploy
  • 29-qism: Miqyoslash — xizmat miqyosi
  • 20-qism (o'tilgan): FastAPI — xizmat qurish

8. Eng yaxshi amaliyotlar

  1. Monolitdan boshlang (domen aniqlanguncha).

  2. Modulli monolit (aniq modullar).

  3. Xizmat = bounded context (mazmunli).

  4. Har xizmat o'z bazasi (mustaqil).

  5. Tarmoq xatosini kutib ishla (qayta urinish, timeout).

  6. Kuzatuv (tracing, markaziy log).

  7. Jamoaga mos tanlang (tashkiliy).

  8. Mikroservis — kerak bo'lganda (moda emas).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # monolit nima?
2.  # mikroservis nima?
3.  # monolit qanday aloqa?
4.  # mikroservis qanday aloqa?
5.  # monolit afzalligi?
6.  # monolit kamchiligi?
7.  # mikroservis afzalligi?
8.  # mikroservis kamchiligi?
9.  # taqsimlangan murakkablik?
10. # qaysidan boshlash?
11. # modulli monolit nima?
12. # Conway qonuni?
Javoblar
  1. Butun tizim bitta ilova
  2. Ko'p mustaqil xizmat
  3. Funksiya chaqiruvi (bir jarayon)
  4. Tarmoq (HTTP, xabar)
  5. Sodda, tez, izchil
  6. Katta bo'lganda qotadi
  7. Mustaqil deploy, miqyos
  8. Taqsimlangan murakkablik (tarmoq)
  9. Tarmoq, izchillik, kuzatuv qiyinligi
  10. Monolitdan (kerak bo'lsa bo'l)
  11. Bir ilova + aniq modullar
  12. Tizim tashkilot muloqotini aks ettiradi

Vazifa 2: Xatolarni tuzating

python
1.  # yangi loyiha 10 xizmat          # monolit

2.  natija = xizmat_chaqir()          # timeout

3.  # ko'p bazada ACID                 # saga

4.  # har funksiya xizmat              # bounded context

5.  # ko'p xizmat bir baza             # o'z bazasi
Javoblar
python
1.  monolitdan boshlash

2.  try/except, qayta urinish, timeout

3.  saga (eventual consistency)

4.  bounded context bo'yicha

5.  har xizmat o'z bazasi

Vazifa 3: Monolit

Tuzing:

  1. Modullar
  2. Funksiya chaqiruvi
  3. Bir baza
  4. Sodda

Vazifa 4: Mikroservis

Tuzing:

  1. Xizmatlar
  2. Tarmoq
  3. Mustaqil baza
  4. Deploy

Vazifa 5: Tarmoq xatosi

Tuzing:

  1. Ishonchsiz xizmat
  2. Qayta urinish
  3. Timeout
  4. Xato

Vazifa 6: Modulli monolit

Tuzing:

  1. Bir ilova
  2. Modullar
  3. Interfeys
  4. Chegara

Vazifa 7: O'ylash

Ko'p jamoa mikroservisdan boshlaydi ("zamonaviy" deb), lekin bu ko'pincha xato — "monolitdan boshlang" tavsiyasi keng tarqalgan. Nima uchun mikroservis "premature" (erta) bo'lishi juda xavfli (monolitni keyin bo'lish, mikroservisni keyin birlashtirishdan osonroq), va nega mikroservis "murakkablikni yo'qotmaydi, balki ko'chiradi" (koddan infratuzilmaga)?

Javob

Qisqa javob: Erta mikroservis xavfli, chunki: chegaralarni bilmaslik (yangi loyihada domen noaniq — qaysi qism qayerga? — noto'g'ri bo'linish); noto'g'ri chegara — qimmat xato (mikroservis chegarasini o'zgartirish = ma'lumotni xizmatlar orasida ko'chirish, API o'zgartirish, ikki xizmatni birlashtirish — juda qiyin, tarmoq/baza aralashgan). Monolitni keyin bo'lish osonroq, chunki: monolitda chegaralar kodda (funksiya, modul — o'zgartirish oson, refactoring), domen aniqlanganda to'g'ri joydan bo'lish mumkin; mikroservisni keyin birlashtirish qiyinroq (ikki mustaqil xizmat, baza, deploy — ularni qayta qo'shish katta ish). Ya'ni monolit → mikroservis (bo'lish) < mikroservis → monolit (birlashtirish) — birinchisi arzonroq, shuning uchun monolitdan boshlash xavfsizroq (noto'g'ri qaror arzonroq tuzatiladi). Mikroservis "murakkablikni ko'chiradi", chunki: monolitda murakkablik kodda (katta kod bazasi, modullar — lekin bir joyda, bir til, bir debug); mikroservisda murakkablik infratuzilmada (tarmoq, deploy, izchillik, kuzatuv, xizmatlararo aloqa — Docker, Kubernetes, tracing, xabar navbatlari). Murakkablik yo'qolmaydi (biznes murakkabligi bir xil) — u koddan operatsiyaga/infratuzilmaga o'tadi. Ko'pincha bu yomon savdo (kichik jamoa uchun): kod murakkabligini boshqarish oson (bir joy, IDE), infratuzilma murakkabligini boshqarish qiyin (tarqoq, ko'p vosita, DevOps). Muhandislik saboqlari: mikroservis — muammoni hal qilmaydi, boshqa muammoga almashtiradi (tanlab); erta optimizatsiya (mikroservis kerak bo'lmasdan) — zarar; monolitdan boshlash — arzon xato (keyin bo'lish oson); murakkablik saqlanadi (ko'chadi) — qayerda boshqarish osonroq, shu tanlanadi.

1. Nega erta xavfli

Domen noaniq → noto'g'ri chegara. Mikroservis chegarasini o'zgartirish — qimmat (ma'lumot ko'chirish, API).

2. Bo'lish vs birlashtirish

Yo'nalish Qiyinlik
Monolit → mikroservis (bo'lish) Osonroq (kod refactoring)
Mikroservis → monolit (birlashtirish) Qiyinroq (mustaqil xizmatlar)

Monolitdan boshlash — arzon xato (tuzatish oson).

3. Murakkablik ko'chadi

  • Monolit: murakkablik kodda (bir joy, bir debug)
  • Mikroservis: murakkablik infratuzilmada (tarmoq, deploy, kuzatuv)

Murakkablik yo'qolmaydi (biznes bir xil) — ko'chadi.

4. Nega yomon savdo (kichik jamoa)

Kod murakkabligi — oson boshqariladi (IDE, bir joy). Infratuzilma — qiyin (tarqoq, DevOps).

5. Muhandislik saboqlari

  1. Mikroservis — muammoni almashtiradi (hal qilmaydi)
  2. Monolitdan boshlash — arzon xato
  3. Murakkablik ko'chadi (koddan infratuzilmaga)
  4. Qayerda boshqarish oson — shu tanlanadi

6. Xulosa

  1. Erta mikroservis — noto'g'ri chegara (qimmat)
  2. Bo'lish < birlashtirish (monolit arzon)
  3. Murakkablik ko'chadi (yo'qolmaydi)
  4. Ehtiyojga qarab (moda emas)

Nimani mustahkamlaydi: 2.5, 2.6-bo'limlar.


Xulosa

Bu darsda monolit va mikroservis arxitekturalarini o'rgandik.

Eng muhim uch fikr:

  1. Monolit va mikroservis. Monolit — butun tizim bitta ilova (bir kod bazasi, jarayon, deploy, baza): modullar funksiya chaqiruvi bilan aloqa; sodda (bir joy), tez (tarmoqsiz), izchil (bir baza — tranzaksiya), oson sinash — lekin katta bo'lganda qotadi. Mikroservis — tizim ko'p mustaqil xizmat ga bo'linadi (har biri o'z kodi, jarayoni, bazasi), tarmoq (HTTP, xabar) orqali aloqa, har xizmat bir bounded context 27.8-bob: mustaqil deploy, miqyoslash, texnologiya erkinligi, jamoa mustaqilligi — lekin taqsimlangan murakkablik narxi.

  2. Afzallik, kamchilik, taqsimlangan murakkablik. Monolit: sodda/tez/izchil (+), qotadi/bir deploy/miqyos hammasi (-). Mikroservis: mustaqil deploy/miqyos/texnologiya (+), taqsimlangan tizim murakkabligi (-): tarmoq ishonchsiz (qayta urinish, timeout), izchillik qiyin (ko'p baza — eventual consistency, saga), taqsimlangan xato (circuit breaker), kuzatuv (distributed tracing), infratuzilma (Docker, Kubernetes — 28-qism). Monolitda "bepul" (bir tranzaksiya, bir log) — mikroservisda ish talab qiladi. Tarmoq — yangi muammolar manbai.

  3. Tanlov, modulli monolit, tashkiliy o'lcham. Tanlov jamoa/hajm/ehtiyojga bog'liq: monolit (kichik jamoa, yangi loyiha, sodda), mikroservis (katta jamoa, mustaqil deploy/miqyos); qoida — monolitdan boshlang ("monolith first" — domen aniqlanguncha bo'lish noto'g'ri chegara beradi; bo'lish birlashtirishdan arzon). Modulli monolit (o'rta yo'l) — bitta ilova (sodda) + aniq modullar (chegarali, interfeys orqali — mikroservis intizomi); kerak bo'lsa modulni xizmatga ajratish oson. Tanlov ko'pincha tashkiliy (Conway qonuni — tizim jamoa strukturasini aks ettiradi): mikroservis "murakkablikni yo'qotmaydi, ko'chiradi" (koddan infratuzilmaga). Monolit/mikroservis — moda emas, jamoa va o'sish rejasiga mos tanlov.

Keyingi darsda hodisaga asoslangan arxitekturani o'rganamiz: komponentlar bir-birini to'g'ridan chaqirmasdan, hodisalar (event) orqali aloqa qilishi — past bog'liqlik, moslashuvchanlik va asinxron oqim bilan reaktiv tizimlar qurish.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
27.9-dars: Monolit va mikroservis — IlmHamroh