ЛЕКЦ 11

Микросервис Архитектур

ЛЕКЦ 11: МИКРОСЕРВИС АРХИТЕКТУР (Microservices Architecture)

Хичээлийн зорилго: Микросервис архитектурын суурь ойлголт, монолит vs микросервис ялгаа, сервис хоорондын харилцаа (REST, gRPC, Message Queue), API Gateway, Service Discovery, Circuit Breaker, Saga Pattern, Event-Driven Architecture, Docker + Kubernetes ашиглан микросервис deploy хийхийг эзэмшүүлэх.

Хамрах хүрээ: Monolith vs Microservices, Bounded Context (DDD), REST & gRPC, Synchronous & Asynchronous Communication, API Gateway, Service Registry (Eureka), Config Server, Circuit Breaker (Resilience4j), Saga Pattern, Event-Driven (Kafka), CQRS, Docker Compose, Kubernetes Deployment, Spring Cloud.



ХЭСЭГ 1: ОНОЛЫН СУУРЬ (Theory & Foundations)

1.1 Монолит архитектур гэж юу вэ?

💡 Зүйрлэл: Монолит = Нэг том байшин. Бүх өрөө (гал тогоо, унтлагын өрөө, оффис) НЭГ ДОТОР. Нэг хана нурвал → Бүх байшин нурна.

Монолит бүтэц:

┌─────────────────────────────────────────┐
│              MONOLITH APP               │
│                                         │
│  ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│  │ Student  │ │ Teacher  │ │ Course  │ │
│  │ Module   │ │ Module   │ │ Module  │ │
│  └────┬─────┘ └────┬─────┘ └────┬────┘ │
│       │             │            │      │
│  ┌────▼─────────────▼────────────▼────┐ │
│  │         SHARED DATABASE            │ │
│  └────────────────────────────────────┘ │
│                                         │
│     1 WAR/JAR  →  1 Server  →  1 DB    │
└─────────────────────────────────────────┘

Монолитийн давуу ба сул талууд:

Давуу талСул тал
Хөгжүүлэхэд ХЯЛБАР (эхэнд)Том болоход НАРИЙСДАГ
Deploy хялбар (1 файл)Нэг module-д алдаа → БҮГД унана
Debug хялбарScale хэцүү (бүхэлдээ scale)
Transaction хялбарТехнологи солиход хэцүү
Тест хялбар (эхэнд)Build удаан (10+ мин)
Bag хүн ойлгоно100+ хөгжүүлэгч → Conflict

1.2 Микросервис архитектур гэж юу вэ?

💡 Зүйрлэл: Микросервис = Хотхоны тусдаа байшингууд. Байшин бүр бие даасан (өөрийн гал тогоо, ус, цахилгаан). Нэг байшин нурсан ч бусад нь зүгээр.

Микросервис бүтэц:

┌────────────┐  ┌────────────┐  ┌────────────┐
│  Student   │  │  Teacher   │  │  Course    │
│  Service   │  │  Service   │  │  Service   │
│            │  │            │  │            │
│  Port:8081 │  │  Port:8082 │  │  Port:8083 │
│  ┌──────┐  │  │  ┌──────┐  │  │  ┌──────┐  │
│  │ DB 1 │  │  │  │ DB 2 │  │  │  │ DB 3 │  │
│  └──────┘  │  │  └──────┘  │  │  └──────┘  │
└─────┬──────┘  └──────┬─────┘  └──────┬─────┘
      │                │               │
      └────────────────┼───────────────┘
                       │
              ┌────────▼────────┐
              │   API Gateway   │
              │   (Port: 8080)  │
              └────────┬────────┘
                       │
                  ┌────▼────┐
                  │ Client  │
                  └─────────┘

Микросервисийн давуу ба сул талууд:

Давуу талСул тал
Бие даасан DEPLOYНарийн түвэгтэй (distributed system)
Бие даасан SCALEСүлжээний latency
Технологи ЧӨЛӨӨТЭЙDistributed transaction хэцүү
Баг бие даасан ажилланаМониторинг НАРИЙН
Fault isolation (нэг унасан ч бусад ok)Debug хэцүү (олон сервис)
Build хурдан (сервис тус бүр)Operational complexity

1.3 Монолит vs Микросервис — Хэзээ аль нь тохирох вэ?

ШинжМонолитМикросервис
Багийн хэмжээ1-10 хөгжүүлэгч10+ хөгжүүлэгч (баг бүрт сервис)
Төслийн хэмжээЖижиг-дундТом, нарийн
TrafficБага-дундИх, тогтмолгүй
Deploy давтамжХоногт 1-2Өдөрт 10+ (сервис тус бүр)
ТехнологиНэг stackОлон stack (polyglot)
ScaleБосоо (vertical)Хэвтээ (horizontal, сервис тус бүр)
Эхлэх✅ Хялбар❌ Нарийн

⚠️ Чухал: "Монолит = Буруу" биш! Эхлэхдээ монолит → Том болсон бол → Микросервис рүү шилжих. "Start with monolith, evolve to microservices."


1.4 Bounded Context (Domain-Driven Design)

Bounded Context гэж юу вэ?

Сервис бүр ӨӨР ӨӨРИЙН домэйн (хүрээ)-г хариуцна. Нэг ойлголт өөр context-д ӨӨӨР утгатай.

┌─────────────────┐    ┌─────────────────┐
│  Student Context │    │  Payment Context │
│                  │    │                  │
│  Student:        │    │  Student:        │
│   - id           │    │   - id           │
│   - name         │    │   - accountId    │
│   - email        │    │   - balance      │
│   - gpa          │    │   - paymentHistory│
│   - department   │    │                  │
│                  │    │  "Student" гэхдээ │
│  "Student" гэхдээ│    │  төлбөрийн мэдээлэл│
│  сурлагын мэдээлэл│   │                  │
└─────────────────┘    └─────────────────┘

Сервис хуваах зарчим:

ЗарчимТайлбар
Single ResponsibilityСервис бүр НЭГ бизнес чиг үүрэг хариуцна
Loose CouplingСервисүүд бие биенээсээ ХАМААРАЛГҮЙ
High CohesionХамааралтай функцүүд НЭГ сервист
Database per ServiceСервис бүр ӨӨРИЙН DB
Autonomous TeamsБаг бүр өөрийн сервисийг бүтнээр хариуцна

1.5 Сервис хоорондын харилцаа (Inter-Service Communication)

1.5.1 Synchronous (Синхрон) — REST, gRPC

Student Service ──── REST/HTTP ────► Teacher Service
       │                                    │
       │  GET /api/teachers/5               │
       │◄── {"id":5,"name":"Дорж"} ─────── │
       │                                    │
       │  Хүлээнэ... (blocking)             │

REST (HTTP):

// Student Service → Teacher Service дуудах
@Service
public class TeacherClient {

    private final RestClient restClient;

    public TeacherClient(RestClient.Builder builder) {
        this.restClient = builder.baseUrl("http://teacher-service:8082").build();
    }

    public TeacherResponse getTeacher(Long id) {
        return restClient.get()
            .uri("/api/teachers/{id}", id)
            .retrieve()
            .body(TeacherResponse.class);
    }
}

gRPC (бинар протокол, хурдан):

ШинжRESTgRPC
ФорматJSON (текст)Protocol Buffers (бинар)
ХурдДундХурдан (10x)
ContractOpenAPI (заавал биш).proto файл (ЗААВАЛ)
StreamingХязгаарлагдмалБүрэн (bi-directional)
Browser✅ Шууд❌ gRPC-Web хэрэгтэй
ХэрэглээPublic APIДотоод сервис хоорондын

1.5.2 Asynchronous (Асинхрон) — Message Queue

Student Service ──── Message ────► [Message Broker] ────► Notification Service
       │                           (Kafka/RabbitMQ)              │
       │  "Student enrolled"                          Email илгээх│
       │                                                         │
       │  Хүлээхгүй! (non-blocking)                              │

Message Queue ашиглах:

// Student Service → Event нийтлэх (Producer)
@Service
public class StudentService {

    private final KafkaTemplate<String, StudentEvent> kafkaTemplate;

    public StudentResponse enroll(EnrollRequest request) {
        Student student = studentRepository.save(toEntity(request));

        // Event нийтлэх — Хүлээхгүй!
        kafkaTemplate.send("student-events",
            new StudentEvent("ENROLLED", student.getId(), student.getName()));

        return toResponse(student);
    }
}

// Notification Service → Event хүлээн авах (Consumer)
@Service
public class NotificationConsumer {

    @KafkaListener(topics = "student-events", groupId = "notification-group")
    public void handleStudentEvent(StudentEvent event) {
        if ("ENROLLED".equals(event.type())) {
            emailService.sendWelcomeEmail(event.studentId());
        }
    }
}

Synchronous vs Asynchronous:

ШинжSynchronous (REST)Asynchronous (Message)
Хүлээх✅ Хариу хүлээнэ❌ Хүлээхгүй
CouplingХүчтэй (сервис ажиллаж байх)Сул (broker замдаа хадгална)
ХурдШууд хариуХожимдсон хариу
НайдвартайСервис унтарвал алдааBroker хадгалаж, дараа илгээнэ
ХэрэглээQuery, CRUDEvent, notification, long task

1.6 API Gateway

API Gateway гэж юу вэ?

Бүх client хүсэлт API Gateway-р дамжина. Gateway → Зөв сервис рүү чиглүүлнэ.

                    ┌─────────────────┐
                    │   API Gateway   │
Client ────────────►│                 │
                    │  /students/*    │──► Student Service
                    │  /teachers/*    │──► Teacher Service
                    │  /courses/*     │──► Course Service
                    │                 │
                    │  + Auth check   │
                    │  + Rate limit   │
                    │  + Load balance │
                    │  + Logging      │
                    └─────────────────┘

API Gateway-ийн үүрэг:

ҮүрэгТайлбар
RoutingURL-аар зөв сервис рүү чиглүүлэх
AuthenticationJWT token шалгах (нэг газраас)
Rate LimitingХүсэлтийн тоо хязгаарлах
Load BalancingОлон instance-д хуваарилах
Logging/MonitoringБүх хүсэлтийг лог бичих
Circuit BreakingУнасан сервис рүү хүсэлт зогсоох
# Spring Cloud Gateway — application.yml
spring:
  cloud:
    gateway:
      routes:
        - id: student-service
          uri: lb://student-service    # Load balanced
          predicates:
            - Path=/api/students/**
          filters:
            - StripPrefix=0

        - id: teacher-service
          uri: lb://teacher-service
          predicates:
            - Path=/api/teachers/**

1.7 Service Discovery (Сервис олох)

Service Discovery яагаад хэрэгтэй вэ?

Микросервис → Олон instance → IP хаяг ДИНАМИК → Хардкодлох БОЛОМЖГҮЙ.

Асуудал:
Student Service → Teacher Service (http://???.???.???.???:8082)
                                    IP хаяг мэдэхгүй!

Шийдэл — Service Registry:
┌─────────────────────────────────────────┐
│         Service Registry (Eureka)       │
│                                         │
│  student-service → 192.168.1.10:8081    │
│                  → 192.168.1.11:8081    │
│                                         │
│  teacher-service → 192.168.1.20:8082    │
│                  → 192.168.1.21:8082    │
│                                         │
│  course-service  → 192.168.1.30:8083    │
└─────────────────────────────────────────┘

Student Service → Registry: "teacher-service хаана байна?"
                → Registry: "192.168.1.20:8082"
                → Teacher Service руу хүсэлт
// Eureka Server
@SpringBootApplication
@EnableEurekaServer
public class RegistryApplication {
    public static void main(String[] args) {
        SpringApplication.run(RegistryApplication.class, args);
    }
}

// Student Service — Eureka Client
// application.yml
spring:
  application:
    name: student-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

1.8 Circuit Breaker Pattern

Circuit Breaker гэж юу вэ?

Сервис унтарсан бол → Дахин дахин дуудахгүй → Автомат таслах → Хэсэг хугацааны дараа дахин оролдох.

         ┌────────┐     ┌────────┐     ┌──────────┐
         │ CLOSED │────►│  OPEN  │────►│HALF-OPEN │
         │        │     │        │     │          │
         │ Normal │     │ Бүгдийг│     │ 1-2 хүсэлт│
         │ ажиллана│    │ блоклох│     │ оролдох   │
         └───┬────┘     └────┬───┘     └────┬─────┘
             │               │              │
         Алдаа >50%      Timeout         Амжилттай?
         → OPEN болох    хүлээх          → CLOSED
                                         Амжилтгүй?
                                         → OPEN
ТөлөвТайлбар
CLOSEDХэвийн ажиллана. Алдааг тоолно
OPENХүсэлт БЛОКЛОГДОНО. Fallback буцаана
HALF-OPENЦөөн хүсэлт оролдоно. OK бол → CLOSED
// Resilience4j — Circuit Breaker
@Service
public class TeacherClient {

    private final RestClient restClient;

    @CircuitBreaker(name = "teacherService", fallbackMethod = "getTeacherFallback")
    public TeacherResponse getTeacher(Long id) {
        return restClient.get()
            .uri("/api/teachers/{id}", id)
            .retrieve()
            .body(TeacherResponse.class);
    }

    // Teacher Service унтарсан бол → Fallback
    private TeacherResponse getTeacherFallback(Long id, Throwable ex) {
        return new TeacherResponse(id, "Unknown Teacher", "N/A");
    }
}
# application.yml — Resilience4j тохиргоо
resilience4j:
  circuitbreaker:
    instances:
      teacherService:
        sliding-window-size: 10          # Сүүлийн 10 хүсэлт шалгана
        failure-rate-threshold: 50       # 50% алдаа → OPEN
        wait-duration-in-open-state: 10s # 10 сек хүлээж → HALF-OPEN
        permitted-number-of-calls-in-half-open-state: 3

1.9 Saga Pattern (Distributed Transaction)

Асуудал: Distributed Transaction

Монолит:
@Transactional → Student INSERT + Payment INSERT + Notification
                 → Аль нэг fail → БҮГД ROLLBACK ✅

Микросервис:
Student Service → OK
Payment Service → FAIL
Notification    → ???
                → Student-г яаж буцаах?? 😱

Saga Pattern:

Сервис бүр ӨӨРИЙН transaction хийж, алдаа гарвал НӨХӨХ transaction (compensation) ажиллуулна.

Choreography Saga (Event-based):

Student Service                Payment Service             Notification
     │                              │                          │
     │── StudentCreated event ──────►                          │
     │                              │                          │
     │                    PaymentProcessed event ──────────────►
     │                              │                          │
     │                              │              NotificationSent event
     │                              │                          │
     │◄── PaymentFailed event ──── │                          │
     │                              │                          │
     │  Compensation:               │                          │
     │  StudentRollback()           │                          │
Saga төрөлТайлбарДавууСул
ChoreographyСервис бүр event-ээр харилцанаЭнгийн, сул холбоосTracking хэцүү
OrchestrationНэг Orchestrator удирданаДараалал тодорхойOrchestrator = Single point
// Choreography Saga — Student Service
@Service
public class StudentService {

    @Transactional
    public StudentResponse enroll(EnrollRequest request) {
        Student student = studentRepository.save(toEntity(request));

        // Event → Payment Service хүлээн авна
        kafkaTemplate.send("student-events",
            new StudentEvent("STUDENT_CREATED", student.getId()));

        return toResponse(student);
    }

    // Payment fail → Compensation
    @KafkaListener(topics = "payment-events", groupId = "student-group")
    public void handlePaymentEvent(PaymentEvent event) {
        if ("PAYMENT_FAILED".equals(event.type())) {
            studentRepository.deleteById(event.studentId());  // Rollback!
        }
    }
}

1.10 Event-Driven Architecture

Event-Driven гэж юу вэ?

Сервисүүд EVENT (үйл явдал)-аар харилцана. Сервис → Event нийтлэх → Сонирхсон сервисүүд → Event хүлээн авах.

┌──────────┐    Event    ┌──────────────┐    Event    ┌──────────────┐
│ Student  │────────────►│              │────────────►│ Notification │
│ Service  │  "enrolled" │    Kafka     │  "enrolled" │   Service    │
└──────────┘             │   Broker     │             └──────────────┘
                         │              │
┌──────────┐             │              │    Event    ┌──────────────┐
│ Payment  │◄────────────│              │────────────►│  Analytics   │
│ Service  │  "enrolled" │              │  "enrolled" │   Service    │
└──────────┘             └──────────────┘             └──────────────┘

Event Sourcing:

УламжлалтEvent Sourcing
Одоогийн STATE хадгалнаБүх EVENT хадгална
UPDATE students SET gpa=3.5Event: {type: GPA_UPDATED, gpa: 3.5}
Өмнөх утга алга болноБүх ТҮҮХ хадгалагдана
ХялбарReplay → State сэргээх

CQRS (Command Query Responsibility Segregation):

Command (бичих):
Client ──► Command Service ──► Write DB (PostgreSQL)
                │
                └──► Event ──► Read DB (Elasticsearch) шинэчлэх

Query (унших):
Client ──► Query Service ──► Read DB (Elasticsearch) ──► Хурдан хариу
ШинжCQRSУламжлалт
БичихWrite DB (normalize)Нэг DB
УншихRead DB (denormalize, хурдан)Нэг DB
ScaleТус тусдаа scaleХамтдаа scale
ХэрэглээИх traffic, нарийн queryЖижиг-дунд апп

1.11 Config Server (Тохиргооны сервер)

Config Server яагаад хэрэгтэй вэ?

Олон сервис → Тохиргоо (DB URL, API key) → НЭГ ГАЗРААС удирдах.

┌──────────────┐       ┌──────────────┐
│ Config Server│◄──────│  Git Repo    │
│              │       │ (config files)│
└──────┬───────┘       └──────────────┘
       │
       ├──────► Student Service (DB URL, JWT secret)
       ├──────► Teacher Service (DB URL, Kafka URL)
       └──────► Course Service  (DB URL, Redis URL)
# Config Server — bootstrap.yml
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/myorg/config-repo
          default-label: main
# student-service.yml (Git repo дотор)
spring:
  datasource:
    url: jdbc:postgresql://db-host:5432/studentdb
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}

jwt:
  secret: ${JWT_SECRET}

teacher-service:
  url: http://teacher-service:8082

1.12 Distributed Tracing (Хянах)

Олон сервис → Хүсэлт хаана удааширсан?

Client → Gateway → Student Service → Teacher Service → DB
                        │                    │
                    100ms              3000ms ← УДААН!

Zipkin / Jaeger + Micrometer:

Trace ID: abc123 (нэг хүсэлтийн бүх алхам)
├── Span 1: Gateway (5ms)
├── Span 2: Student Service (100ms)
│   ├── Span 3: Teacher Service call (3000ms) ← BOTTLENECK!
│   └── Span 4: DB query (20ms)
└── Total: 3125ms
# application.yml — Micrometer Tracing
management:
  tracing:
    sampling:
      probability: 1.0   # 100% хүсэлт trace хийх (production-д 0.1)
  zipkin:
    tracing:
      endpoint: http://zipkin:9411/api/v2/spans

1.13 Database per Service

Сервис бүрт тусдаа DB:

┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│Student Service│   │Teacher Service│   │Course Service │
│               │   │               │   │               │
│  PostgreSQL   │   │   MongoDB     │   │  PostgreSQL   │
│  students DB  │   │  teachers DB  │   │  courses DB   │
└───────────────┘   └───────────────┘   └───────────────┘
      ↑                    ↑                    ↑
   Polyglot Persistence: Сервис бүр ӨӨРТ ТОХИРОХ DB сонгоно
ЗарчимТайлбар
Тусдаа DBСервис бүр ӨӨРИЙН DB → Бие даасан deploy, scale
Шууд хандахгүйStudent Service → Teacher DB руу ШУУД хандахгүй!
API-аарTeacher мэдээлэл хэрэгтэй бол → Teacher Service API дуудах
PolyglotСервис бүр өөрт тохирох DB (SQL, NoSQL, Redis)

1.14 Kubernetes дээр Микросервис deploy

Kubernetes ойлголт:

┌─────────────────── Kubernetes Cluster ───────────────────┐
│                                                          │
│  ┌─── Node 1 ───────────┐  ┌─── Node 2 ───────────┐    │
│  │                       │  │                       │    │
│  │  ┌─── Pod ────────┐  │  │  ┌─── Pod ────────┐  │    │
│  │  │ Student Svc    │  │  │  │ Student Svc    │  │    │
│  │  │ (replica 1)    │  │  │  │ (replica 2)    │  │    │
│  │  └────────────────┘  │  │  └────────────────┘  │    │
│  │                       │  │                       │    │
│  │  ┌─── Pod ────────┐  │  │  ┌─── Pod ────────┐  │    │
│  │  │ Teacher Svc    │  │  │  │ Course Svc     │  │    │
│  │  │ (replica 1)    │  │  │  │ (replica 1)    │  │    │
│  │  └────────────────┘  │  │  └────────────────┘  │    │
│  │                       │  │                       │    │
│  └───────────────────────┘  └───────────────────────┘    │
│                                                          │
│  Service (K8s) = Load Balancer + DNS                     │
│  student-service:8081 → Pod replica 1 эсвэл 2            │
└──────────────────────────────────────────────────────────┘
# student-service-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: student-service
spec:
  replicas: 2
  selector:
    matchLabels:
      app: student-service
  template:
    metadata:
      labels:
        app: student-service
    spec:
      containers:
        - name: student-service
          image: myregistry/student-service:1.0.0
          ports:
            - containerPort: 8081
          env:
            - name: DB_URL
              valueFrom:
                secretKeyRef:
                  name: student-db-secret
                  key: url
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "512Mi"
              cpu: "500m"
          livenessProbe:
            httpGet:
              path: /actuator/health
              port: 8081
            initialDelaySeconds: 30
            periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: student-service
spec:
  selector:
    app: student-service
  ports:
    - port: 8081
      targetPort: 8081
  type: ClusterIP

1.15 Микросервис шилдэг туршлагууд (Best Practices)

#ЗарчимТайлбар
1Database per ServiceСервис бүр өөрийн DB
2API GatewayНэг entry point, auth, routing
3Service DiscoveryДинамик IP → Registry
4Circuit BreakerУнасан сервис → Автомат таслах
5Event-DrivenAsync харилцаа (Kafka, RabbitMQ)
6Config ServerТохиргоо нэг газраас
7Distributed TracingХүсэлтийг хянах (Zipkin)
8Health CheckСервис бүрт /actuator/health
9ContainerizationDocker → Kubernetes
10CI/CD per ServiceСервис бүрт тусдаа pipeline
11Backward CompatibilityAPI хувилбарлалт (v1, v2)
12Centralized LoggingБүх лог нэг газар (ELK Stack)
13IdempotencyДавтагдсан хүсэлт → Ижил үр дүн
14Correlation IDХүсэлт бүрт ID → Бүх сервисээр дагах
15Graceful ShutdownСервис зогсоход ажиллаж буй хүсэлт дуусгах


ХЭСЭГ 2: ТҮЛХҮҮР ҮГ БА МЭРГЭЖЛИЙН НЭР ТОМЬЁО (Keywords & Glossary)

#Англи нэр томьёоМонгол утгаДэлгэрэнгүй тайлбар
1MonolithМонолитБүх функц НЭГ апп дотор — 1 WAR/JAR, 1 DB.
2MicroserviceМикросервисБие даасан, жижиг сервисүүд — Тусдаа deploy, DB.
3API GatewayAPI гарцБүх хүсэлт дамжих НЭГ ЦЭГИЙГ удирдагч — Routing, Auth, Rate Limit.
4Service DiscoveryСервис олохСервисүүдийн IP хаягийг динамикаар олох — Eureka, Consul.
5Service RegistryСервис бүртгэлСервисүүдийн хаяг хадгалах газар — Eureka Server.
6Circuit BreakerХэлхээ таслагчУнасан сервис рүү хүсэлт таслах — Resilience4j.
7Saga PatternСага загварDistributed transaction-г event/compensation-аар зохицуулах.
8ChoreographyХореографиСервис бүр event-ээр бие даасан харилцах Saga.
9OrchestrationОркестрчилолНэг Orchestrator бүх алхмыг удирдах Saga.
10Event-DrivenҮйл явдалд суурилсанСервисүүд EVENT-ээр харилцана — Kafka, RabbitMQ.
11Event SourcingҮйл явдлын эх сурвалжState биш EVENT бүрийг хадгалах — Түүх бүрэн.
12CQRSКоманд-Асуулгын тусгаарлалтБичих (Command) ба Унших (Query) тусдаа DB/model.
13Message BrokerЗурвас зуучлагчСервис хооронд мэдээ дамжуулагч — Kafka, RabbitMQ.
14KafkaКафкаDistributed event streaming platform — LinkedIn.
15RabbitMQRabbitMQAMQP message broker — Дараалал удирдах.
16gRPCgRPCGoogle-ийн бинар RPC framework — REST-ээс хурдан.
17Protocol BuffersProtobufgRPC-ийн бинар серилизаци формат (.proto).
18RESTRESTHTTP + JSON ашигласан синхрон API.
19Bounded ContextХязгаарлагдсан контекстDDD — Сервисийн хариуцах домэйн хүрээ.
20DDDДомэйн хөтлөгдсөн дизайнDomain-Driven Design — Бизнес домайнаар сервис хуваах.
21Config ServerТохиргооны серверБүх сервисийн тохиргоог нэг газраас удирдах.
22Distributed TracingТархсан хянахХүсэлтийг олон сервисээр дагаж хянах — Zipkin, Jaeger.
23Trace IDХянах IDНэг хүсэлтийн бүх алхмыг холбох ID.
24SpanХэрчимTrace дотор нэг сервисийн ажлын нэгж.
25Load BalancingАчаалал тэнцвэржүүлэхХүсэлтийг олон instance-д тэнцүү хуваарилах.
26Health CheckЭрүүл мэнд шалгалтСервис ажиллаж буйг шалгах (/actuator/health).
27FallbackНөөц хариуСервис алдаа гаргавал буцаах ЗАЙ хариу.
28IdempotencyДавтагдах боломжИжил хүсэлт олон удаа → Ижил үр дүн (давхар үүсгэхгүй).
29Polyglot PersistenceОлон хэлт хадгалалтСервис бүр өөр DB (PostgreSQL, MongoDB, Redis).
30Sidecar PatternХажуугийн загварСервис хажууд нэмэлт container (logging, proxy).
31Service MeshСервис торСервис хоорондын харилцааг удирдагч дэд бүтэц — Istio.
32KubernetesКубернетисContainer orchestration platform — Pod, Deployment, Service.
33HelmХелмKubernetes-ийн package manager — Chart.
34Docker ComposeDocker ComposeОлон container-г нэг файлаар удирдах.
35Correlation IDХамааралын IDХүсэлт бүрт ID → Бүх сервисийн лог-д дагах.
36ELK StackELK StackElasticsearch + Logstash + Kibana — Centralized logging.
37Backward CompatibilityБуцаан нийцэмжAPI өөрчлөхөд хуучин client-д нөлөөлөхгүй (v1, v2).
38Graceful ShutdownЗөөлөн зогсолтСервис зогсоход ажиллаж буй хүсэлтийг дуусгаад зогсох.
39Spring CloudSpring CloudМикросервис framework — Gateway, Eureka, Config, Resilience4j.
40Strangler Fig PatternЗүлгэлтийн загварМонолитоос микросервис рүү аажмаар шилжих стратеги.


ХЭСЭГ 3: ЛАБОРАТОРИ БА ПРАКТИК ЗААВАР (Labs & Step-by-Step Guide)

3.1 Лабораторийн зорилго

Энэ лабораторид та:

  1. 3 микросервис үүсгэх (Student, Teacher, Gateway)
  2. Service Discovery (Eureka) тохируулах
  3. Сервис хоорондын REST дуудлага хийх
  4. Circuit Breaker (Resilience4j) нэмэх
  5. Docker Compose-оор бүгдийг ажиллуулах

Хэл: Java 17+ / Spring Boot 3.x | Framework: Spring Cloud | Хэрэгсэл: Docker, Docker Compose


3.2 Лаб 1: Eureka Service Registry

Алхам 1: Eureka Server үүсгэх

pom.xml:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

Application class:

@SpringBootApplication
@EnableEurekaServer
public class RegistryApplication {
    public static void main(String[] args) {
        SpringApplication.run(RegistryApplication.class, args);
    }
}

application.yml:

server:
  port: 8761

eureka:
  client:
    register-with-eureka: false   # Өөрийгөө бүртгэхгүй
    fetch-registry: false
  server:
    enable-self-preservation: false

Алхам 2: Student Service — Eureka Client

pom.xml:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

application.yml:

server:
  port: 8081

spring:
  application:
    name: student-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

Алхам 3: Teacher Service — Eureka Client

server:
  port: 8082

spring:
  application:
    name: teacher-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

Шалгах:

# Eureka Dashboard
# http://localhost:8761 → student-service, teacher-service харагдана

3.3 Лаб 2: Сервис хоорондын REST дуудлага

Student Service → Teacher Service дуудах

// Student Service — RestClient тохиргоо
@Configuration
public class RestClientConfig {

    @Bean
    @LoadBalanced   // Eureka-аар IP хаяг олно
    public RestClient.Builder restClientBuilder() {
        return RestClient.builder();
    }
}
// Student Service — Teacher Client
@Service
public class TeacherClient {

    private final RestClient restClient;

    public TeacherClient(RestClient.Builder builder) {
        this.restClient = builder
            .baseUrl("http://teacher-service")  // Eureka нэр (IP биш!)
            .build();
    }

    public TeacherResponse getTeacher(Long id) {
        return restClient.get()
            .uri("/api/teachers/{id}", id)
            .retrieve()
            .body(TeacherResponse.class);
    }
}
// Student Service — Controller
@RestController
@RequestMapping("/api/students")
public class StudentController {

    private final StudentService studentService;
    private final TeacherClient teacherClient;

    @GetMapping("/{id}/with-teacher")
    public StudentWithTeacherResponse getStudentWithTeacher(@PathVariable Long id) {
        StudentResponse student = studentService.getById(id);
        TeacherResponse teacher = teacherClient.getTeacher(student.teacherId());
        return new StudentWithTeacherResponse(student, teacher);
    }
}

public record StudentWithTeacherResponse(
    StudentResponse student,
    TeacherResponse teacher
) {}

Тест хийх:

# Student + Teacher мэдээлэл хамт авах
curl http://localhost:8081/api/students/1/with-teacher

# Хариу:
# {
#   "student": {"id":1,"name":"Бат","teacherId":5},
#   "teacher": {"id":5,"name":"Дорж","department":"CS"}
# }

3.4 Лаб 3: Circuit Breaker (Resilience4j)

Алхам 1: Dependency нэмэх

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>

Алхам 2: Circuit Breaker нэмэх

@Service
public class TeacherClient {

    private final RestClient restClient;

    @CircuitBreaker(name = "teacherService", fallbackMethod = "getTeacherFallback")
    @Retry(name = "teacherService")
    public TeacherResponse getTeacher(Long id) {
        return restClient.get()
            .uri("/api/teachers/{id}", id)
            .retrieve()
            .body(TeacherResponse.class);
    }

    // Teacher Service унтарсан бол → Fallback хариу
    private TeacherResponse getTeacherFallback(Long id, Throwable ex) {
        return new TeacherResponse(id, "Багшийн мэдээлэл түр авах боломжгүй", "N/A");
    }
}

Алхам 3: Тохиргоо

# application.yml
resilience4j:
  circuitbreaker:
    instances:
      teacherService:
        sliding-window-size: 10
        failure-rate-threshold: 50
        wait-duration-in-open-state: 10s
        permitted-number-of-calls-in-half-open-state: 3
  retry:
    instances:
      teacherService:
        max-attempts: 3
        wait-duration: 1s

Тест хийх:

# Teacher Service ажиллаж байхад
curl http://localhost:8081/api/students/1/with-teacher
# → {"student":{...},"teacher":{"id":5,"name":"Дорж"}}

# Teacher Service ЗОГСООХ (docker stop teacher-service)
curl http://localhost:8081/api/students/1/with-teacher
# → {"student":{...},"teacher":{"id":5,"name":"Багшийн мэдээлэл түр авах боломжгүй"}}
# Circuit Breaker → Fallback ажиллалаа!

3.5 Лаб 4: API Gateway (Spring Cloud Gateway)

Алхам 1: Gateway үүсгэх

pom.xml:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

Алхам 2: Gateway тохиргоо

server:
  port: 8080

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: student-service
          uri: lb://student-service
          predicates:
            - Path=/api/students/**

        - id: teacher-service
          uri: lb://teacher-service
          predicates:
            - Path=/api/teachers/**

      default-filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 10
            redis-rate-limiter.burstCapacity: 20

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

Тест хийх:

# Gateway-р дамжуулж дуудах (8080 port)
curl http://localhost:8080/api/students
# → Student Service-ийн хариу

curl http://localhost:8080/api/teachers
# → Teacher Service-ийн хариу

# Client зөвхөн 8080 порт мэдэхэд хангалттай!

3.6 Лаб 5: Docker Compose — Бүгдийг нэгтгэх

docker-compose.yml

version: '3.8'

services:
  # Eureka Registry
  registry:
    build: ./registry-service
    ports:
      - "8761:8761"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8761/actuator/health"]
      interval: 10s
      retries: 5

  # Student Service
  student-service:
    build: ./student-service
    ports:
      - "8081:8081"
    environment:
      - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://registry:8761/eureka/
      - SPRING_DATASOURCE_URL=jdbc:postgresql://student-db:5432/studentdb
      - SPRING_DATASOURCE_USERNAME=${DB_USERNAME}
      - SPRING_DATASOURCE_PASSWORD=${DB_PASSWORD}
    depends_on:
      registry:
        condition: service_healthy
      student-db:
        condition: service_healthy

  # Teacher Service
  teacher-service:
    build: ./teacher-service
    ports:
      - "8082:8082"
    environment:
      - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://registry:8761/eureka/
      - SPRING_DATASOURCE_URL=jdbc:postgresql://teacher-db:5432/teacherdb
      - SPRING_DATASOURCE_USERNAME=${DB_USERNAME}
      - SPRING_DATASOURCE_PASSWORD=${DB_PASSWORD}
    depends_on:
      registry:
        condition: service_healthy
      teacher-db:
        condition: service_healthy

  # API Gateway
  api-gateway:
    build: ./api-gateway
    ports:
      - "8080:8080"
    environment:
      - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://registry:8761/eureka/
    depends_on:
      registry:
        condition: service_healthy
      student-service:
        condition: service_started
      teacher-service:
        condition: service_started

  # Student DB
  student-db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: studentdb
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - student-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME}"]
      interval: 5s
      retries: 5

  # Teacher DB
  teacher-db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: teacherdb
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - teacher-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME}"]
      interval: 5s
      retries: 5

volumes:
  student-data:
  teacher-data:

Ажиллуулах:

# .env файл
echo "DB_USERNAME=admin" > .env
echo "DB_PASSWORD=secret123" >> .env

# Бүгдийг эхлүүлэх
docker-compose up -d --build

# Шалгах
curl http://localhost:8080/api/students    # Gateway → Student Service
curl http://localhost:8080/api/teachers    # Gateway → Teacher Service
curl http://localhost:8761                 # Eureka Dashboard

# Зогсоох
docker-compose down -v


ХЭСЭГ 4: ШАЛГАЛТЫН АСУУЛТ (Knowledge Check — 100 тест)

Тест 1

Монолит архитектурын гол шинж юу вэ?

  • A) Олон DB
  • B) Бүх функц НЭГ апп дотор — 1 WAR/JAR, 1 DB, 1 Deploy
  • C) Олон сервис
  • D) Бие даасан deploy

Зөв хариулт: B

Тайлбар: Монолит = Student, Teacher, Course бүгд НЭГ апп. Нэг deploy, нэг DB. Жижиг төсөлд тохиромжтой. Том болоход нарийсдаг.

Тест 2

Микросервис архитектурын гол шинж юу вэ?

  • A) Нэг DB
  • B) БИЕ ДААСАН, жижиг сервисүүд — Тус тусын deploy, DB, технологи
  • C) Нэг апп
  • D) Нэг сервер

Зөв хариулт: B

Тайлбар: Микросервис = Student Service (DB 1), Teacher Service (DB 2), Course Service (DB 3). Бие даасан deploy, scale. Баг бүр өөрийн сервисийг хариуцна.

Тест 3

Монолитийн хамгийн том сул тал юу вэ?

  • A) Хурдан
  • B) Нэг module-д алдаа → БҮХЭЛ АПП унах, scale хэцүү (бүхэлдээ)
  • C) Хялбар
  • D) Deploy хурдан

Зөв хариулт: B

Тайлбар: Teacher module crash → Student, Course бүгд ЗОГСОНО. Scale: Student module-д их traffic → Бүхэлдээ scale хийх хэрэгтэй (Teacher, Course-г ч).

Тест 4

Микросервисийн хамгийн том сул тал юу вэ?

  • A) Хурдан
  • B) Distributed system-ийн НАРИЙН ТҮВЭГТЭЙ байдал — Network latency, distributed transaction
  • C) Deploy хялбар
  • D) Scale хялбар

Зөв хариулт: B

Тайлбар: Network call = Хүсэлт замдаа удаашрах. Distributed transaction = Олон сервисийн DB хоорондын ACID хэцүү. Debug = Олон сервис → Хаана алдаа гарсан? Operational complexity.

Тест 5

"Database per Service" зарчим юу вэ?

  • A) Бүх сервис нэг DB
  • B) Сервис бүр ӨӨРИЙН ТУСДАА DB — Бие даасан deploy, scale
  • C) DB байхгүй
  • D) Shared DB

Зөв хариулт: B

Тайлбар: Student Service → PostgreSQL (students DB). Teacher Service → MongoDB (teachers DB). Бие биеийн DB руу ШУУД ХАНДАХГҮЙ! API-аар дуудна.

Тест 6

API Gateway юу хийдэг вэ?

  • A) Database
  • B) Бүх client хүсэлтийн НЭГ ENTRY POINT — Routing, Auth, Rate Limiting, Load Balancing
  • C) Код бичих
  • D) Тест хийх

Зөв хариулт: B

Тайлбар: Client → Gateway (8080) → /students/* → Student Service. /teachers/* → Teacher Service. Client зөвхөн Gateway-ийн хаяг мэдэхэд хангалттай. JWT auth нэг газраас.

Тест 7

Service Discovery яагаад хэрэгтэй вэ?

  • A) Шаардлагагүй
  • B) Микросервисийн IP хаяг ДИНАМИК → Хардкодлох БОЛОМЖГҮЙ → Автомат олох
  • C) Зөвхөн тест
  • D) Зөвхөн deploy

Зөв хариулт: B

Тайлбар: Docker, K8s → Container шинэ IP авна. Eureka registry: student-service → 192.168.1.10:8081. Сервис Eureka-аас бусад сервисийн хаягийг олно.

Тест 8

Eureka гэж юу вэ?

  • A) Database
  • B) Netflix-ийн SERVICE REGISTRY — Сервисүүд бүртгүүлж, бие биенээ олох
  • C) Message broker
  • D) API Gateway

Зөв хариулт: B

Тайлбар: Eureka Server (8761) = Бүртгэл. Сервис бүр эхлэхэд Eureka-д бүртгүүлнэ. Бусад сервис Eureka-аас хаяг асууна. Dashboard: http://localhost:8761.

Тест 9

Circuit Breaker Pattern юу хийдэг вэ?

  • A) Сервис эхлүүлэх
  • B) Унасан сервис рүү хүсэлт АВТОМАТ ТАСЛАЖ, fallback буцаах — Cascade failure-аас хамгаалах
  • C) DB холбох
  • D) Код compile

Зөв хариулт: B

Тайлбар: Teacher Service унтарсан → Student Service дахин дахин дуудна → Student Service ч удаашрана → Бүгд НУРНА (cascade failure). Circuit Breaker = Таслах → Fallback → Хамгаалах.

Тест 10

Circuit Breaker-ийн 3 төлөв юу вэ?

  • A) Start, Stop, Restart
  • B) CLOSED (хэвийн), OPEN (блоклох), HALF-OPEN (оролдох)
  • C) On, Off, Standby
  • D) Active, Passive, Idle

Зөв хариулт: B

Тайлбар: CLOSED = Хэвийн ажиллана, алдаа тоолно. OPEN = 50%+ алдаа → Блоклох, fallback. HALF-OPEN = Хугацааны дараа 1-2 хүсэлт оролдоно → OK бол CLOSED.

Тест 11

Fallback method юу хийдэг вэ?

  • A) Алдаа устгах
  • B) Сервис алдаа гаргахад НӨӨЦ ХАРИУ буцаах — Хэрэглэгчид бүрэн алдаа харуулахгүй
  • C) Сервис эхлүүлэх
  • D) DB холбох

Зөв хариулт: B

Тайлбар: getTeacherFallback() = Teacher Service унтарсан бол → "Мэдээлэл түр авах боломжгүй" буцаана. Student-ийн мэдээлэл харагдана, Teacher хэсэг → Fallback.

Тест 12

Synchronous communication (REST) -ийн сул тал юу вэ?

  • A) Хурдан
  • B) Хүлээнэ (BLOCKING) — Дуудагдсан сервис унтарвал → АЛДАА, coupling хүчтэй
  • C) Хялбар
  • D) Найдвартай

Зөв хариулт: B

Тайлбар: Student → Teacher REST call → Teacher 5 секунд хариу өгөхгүй → Student 5 сек БЛОКЛОГДОНО → Client 5 сек хүлээнэ. Teacher down = Student ч алдаа.

Тест 13

Asynchronous communication (Message Queue) -ийн давуу тал юу вэ?

  • A) Шууд хариу
  • B) ХҮЛЭЭХГҮЙ (non-blocking) — Broker мэдээ хадгалж, дараа хүргэнэ → Сул coupling
  • C) Хурд бага
  • D) Нарийн

Зөв хариулт: B

Тайлбар: Student → Kafka "enrolled" event → Буцаана. Notification Service → Kafka-аас "enrolled" event хүлээн авч → Email илгээнэ. Student Service хүлээхгүй!

Тест 14

Kafka гэж юу вэ?

  • A) Database
  • B) DISTRIBUTED EVENT STREAMING platform — Сервис хооронд event дамжуулах (message broker)
  • C) API Gateway
  • D) Web framework

Зөв хариулт: B

Тайлбар: Kafka = LinkedIn бүтээсэн. Topic → Partition → Consumer Group. Дараалал хадгалагддаг (replay боломжтой). Их traffic-д тохиромжтой. Producer → Topic → Consumer.

Тест 15

Saga Pattern юу вэ?

  • A) Design pattern
  • B) Микросервисийн DISTRIBUTED TRANSACTION удирдах загвар — Compensation ашиглан rollback
  • C) UI pattern
  • D) Database pattern

Зөв хариулт: B

Тайлбар: Student created → Payment failed → Student ROLLBACK (compensation). Монолитийн @Transactional-г ОРЛОХ. Event-аар алхам бүрийг зохицуулна.

Тест 16

Choreography Saga vs Orchestration Saga-ийн ялгаа юу вэ?

  • A) Ялгаагүй
  • B) Choreography = Сервис бүр EVENT-ээр бие даасан, Orchestration = НЭГ ORCHESTRATOR удирдана
  • C) Choreography = Удирдагчтай
  • D) Orchestration = Бие даасан

Зөв хариулт: B

Тайлбар: Choreography = Тус тусдаа бүжиглэдэг (event). Orchestration = Нэг хөгжимчин удирдана. Choreography = Энгийн, гэхдээ tracking хэцүү. Orchestration = Тодорхой, гэхдээ single point.

Тест 17

Bounded Context (DDD) гэж юу вэ?

  • A) Database хүрээ
  • B) Сервисийн хариуцах ДОМЭЙН ХҮРЭЭ — "Student" нэр өөр context-д ӨӨӨР утгатай
  • C) API хүрээ
  • D) Тест хүрээ

Зөв хариулт: B

Тайлбар: Student Context: Student = {name, gpa, department}. Payment Context: Student = {accountId, balance}. Ижил нэр, ӨӨӨР утга. Сервис = Bounded Context.

Тест 18

Event-Driven Architecture гэж юу вэ?

  • A) REST дуудлага
  • B) Сервисүүд EVENT (үйл явдал)-аар харилцана — Publish/Subscribe загвар
  • C) Shared DB
  • D) Synchronous

Зөв хариулт: B

Тайлбар: Student Service → "StudentEnrolled" event → Kafka → Notification (email), Payment (invoice), Analytics (dashboard). Олон сервис НЭГ event хүлээн авна.

Тест 19

Event Sourcing гэж юу вэ?

  • A) Одоогийн state хадгалах
  • B) State биш, бүх EVENT (өөрчлөлт бүр)-г ХАДГАЛАХ — Түүх бүрэн, replay боломжтой
  • C) Зөвхөн шинэ event
  • D) Event устгах

Зөв хариулт: B

Тайлбар: Уламжлалт: UPDATE gpa=3.5 (хуучин утга алга). Event Sourcing: Event 1: Created(gpa=2.0), Event 2: GpaUpdated(3.0), Event 3: GpaUpdated(3.5). Бүх түүх!

Тест 20

CQRS гэж юу вэ?

  • A) Нэг DB
  • B) Бичих (Command) ба Унших (Query) -г ТУСДАА MODEL/DB-ээр удирдах
  • C) Зөвхөн бичих
  • D) Зөвхөн унших

Зөв хариулт: B

Тайлбар: Command → Write DB (PostgreSQL, normalized). Query → Read DB (Elasticsearch, denormalized, хурдан). Бичих бага, унших ихтэй системд тохиромжтой.

Тест 21

@LoadBalanced annotation юу хийдэг вэ?

  • A) Сервис устгах
  • B) RestClient-г EUREKA-аар сервис олж, олон instance-д АЧААЛАЛ ХУВААРИЛАХ
  • C) DB холбох
  • D) Тест хийх

Зөв хариулт: B

Тайлбар: @LoadBalanced RestClient.Builderhttp://teacher-service → Eureka-аас IP олно → 2 instance байвал → Round-robin хуваарилна. IP хардкодлохгүй.

Тест 22

gRPC REST-ээс юугаараа давуу вэ?

  • A) JSON ашиглана
  • B) Protocol Buffers (БИНАР) = JSON-оос 10x ХУРДАН, bi-directional streaming
  • C) Browser-д хялбар
  • D) Тохируулахад хялбар

Зөв хариулт: B

Тайлбар: REST = JSON (текст, том). gRPC = Protobuf (бинар, жижиг, хурдан). Дотоод сервис хоорондын дуудлагад gRPC тохиромжтой. Public API = REST (browser).

Тест 23

Spring Cloud Gateway юу хийдэг вэ?

  • A) Database
  • B) Микросервисийн API GATEWAY — Routing, Load Balancing, Rate Limiting, Filtering
  • C) Message broker
  • D) Service registry

Зөв хариулт: B

Тайлбар: lb://student-service = Load balanced URI. Path=/api/students/** = Routing. Filter = Auth, Rate Limit, Logging. Бүх client хүсэлт Gateway-р дамжина.

Тест 24

Config Server яагаад хэрэгтэй вэ?

  • A) Шаардлагагүй
  • B) Олон сервисийн тохиргоог (DB URL, API key) НЭГ ГАЗРААС удирдах — Git repo
  • C) Зөвхөн тест
  • D) Зөвхөн deploy

Зөв хариулт: B

Тайлбар: 10 сервис × 3 орчин (dev, staging, prod) = 30 тохиргоо. Config Server = Git repo-д хадгалж, нэг газраас удирдана. DB_URL өөрчлөхөд сервис бүрийг засахгүй.

Тест 25

Distributed Tracing яагаад хэрэгтэй вэ?

  • A) Шаардлагагүй
  • B) Хүсэлт ОЛОН СЕРВИСЭЭР дамжихад хаана УДААШИРСАН, АЛДАА ГАРСНЫГ олох
  • C) Зөвхөн лог
  • D) Зөвхөн мониторинг

Зөв хариулт: B

Тайлбар: Client → Gateway (5ms) → Student (100ms) → Teacher (3000ms!) → DB (20ms). Zipkin/Jaeger: Trace ID-аар бүх алхмыг хянана → Teacher Service = Bottleneck!

Тест 26

Trace ID гэж юу вэ?

  • A) User ID
  • B) Нэг хүсэлтийн БҮХ сервисийн алхмыг ХОЛБОХ дахин давтагдашгүй ID
  • C) Session ID
  • D) Transaction ID

Зөв хариулт: B

Тайлбар: Client хүсэлт → Trace ID: abc123 үүснэ → Gateway (abc123) → Student (abc123) → Teacher (abc123). Бүх сервисийн лог-д abc123 → НЭГ хүсэлтийн бүх алхмыг хянана.

Тест 27

Polyglot Persistence гэж юу вэ?

  • A) Нэг DB
  • B) Сервис бүр ӨӨРТ ТОХИРОХ DB сонгох — PostgreSQL, MongoDB, Redis
  • C) Зөвхөн SQL
  • D) Зөвхөн NoSQL

Зөв хариулт: B

Тайлбар: Student = PostgreSQL (relational). Teacher = MongoDB (document). Cache = Redis. Search = Elasticsearch. Сервис бүр бизнес шаардлагад тохирох DB сонгоно.

Тест 28

Idempotency яагаад микросервисд чухал вэ?

  • A) Шаардлагагүй
  • B) Сүлжээний алдаагаар ДАВТАГДСАН хүсэлт → ИЖИЛ ҮР ДҮН (давхар бичлэг үүсгэхгүй)
  • C) Хурдасгах
  • D) Зөвхөн тест

Зөв хариулт: B

Тайлбар: Network timeout → Client retry → Сервер 2 удаа хүлээн авна → Idempotency key-гүй бол 2 Student үүснэ! Idempotency key ашиглаж 1 удаа л боловсруулна.

Тест 29

Service Mesh (Istio) гэж юу вэ?

  • A) Database
  • B) Сервис хоорондын харилцааг удирдах ДЭД БҮТЭЦ — mTLS, traffic, observability
  • C) Message broker
  • D) API Gateway

Зөв хариулт: B

Тайлбар: Istio = Sidecar proxy (Envoy) сервис бүрийн хажууд. mTLS (encrypt), retry, circuit breaker, traffic splitting → Кодонд ХҮРЭХГҮЙГЭЭР дэд бүтцийн түвшинд.

Тест 30

Strangler Fig Pattern юу вэ?

  • A) Шинэ апп бичих
  • B) Монолитоос микросервис рүү ААЖМААР шилжих — Хуучныг нэг нэгээр солих
  • C) Бүгдийг нэг дор солих
  • D) Монолит хэвээр

Зөв хариулт: B

Тайлбар: Бүгдийг нэг дор солих = Эрсдэлтэй. Strangler Fig = Student module → Student Service болгож гаргах → OK → Teacher module → ... Аажмаар шилжих.

Тест 31

@KafkaListener юу хийдэг вэ?

  • A) Kafka руу илгээх
  • B) Kafka TOPIC-оос event (мэдээ) ХҮЛЭЭН АВАХ — Consumer
  • C) Topic устгах
  • D) Kafka эхлүүлэх

Зөв хариулт: B

Тайлбар: @KafkaListener(topics = "student-events") = "student-events" topic-д шинэ event ирэхэд автоматаар method дуудагдана. Consumer = Event handler.

Тест 32

KafkaTemplate.send() юу хийдэг вэ?

  • A) Event хүлээн авах
  • B) Kafka TOPIC руу event (мэдээ) ИЛГЭЭХ — Producer
  • C) Topic устгах
  • D) Consumer үүсгэх

Зөв хариулт: B

Тайлбар: kafkaTemplate.send("student-events", event) = "student-events" topic руу event нийтлэх. Producer → Topic → Consumer(s). Олон consumer хүлээн авч болно.

Тест 33

lb://student-service (Gateway) дахь lb:// юу вэ?

  • A) HTTP protocol
  • B) LOAD BALANCED — Eureka-аас олж, олон instance-д тэнцүү хуваарилах
  • C) Database
  • D) File protocol

Зөв хариулт: B

Тайлбар: lb://student-service = Eureka registry-аас student-service хайна → 2 instance байвал → Round-robin (1-р, 2-р, 1-р...). Load balancing = Ачаалал тэнцвэржүүлэх.

Тест 34

Health Check (/actuator/health) яагаад чухал вэ?

  • A) Шаардлагагүй
  • B) Сервис АМЬД, ажиллаж буйг АВТОМАТ шалгах — K8s, Eureka, Load Balancer ашиглана
  • C) Зөвхөн лог
  • D) Зөвхөн тест

Зөв хариулт: B

Тайлбар: /actuator/health{"status":"UP"}. K8s livenessProbe → Health check fail = Pod restart. Eureka → Unhealthy сервис → Registry-аас хасна. Автомат мониторинг.

Тест 35

Correlation ID гэж юу вэ?

  • A) User ID
  • B) Хүсэлт бүрт НЭМСЭН ID → Бүх сервисийн ЛОГ-д дагаж, ХЯНАХ
  • C) Session ID
  • D) DB ID

Зөв хариулт: B

Тайлбар: Client → Header: X-Correlation-ID: abc123. Gateway → Student → Teacher бүгд лог-д abc123 бичнэ. Алдаа гарвал abc123-аар бүх сервисийн логоос олно.

Тест 36

Cascade Failure гэж юу вэ?

  • A) Нэг сервис унах
  • B) Нэг сервис унаснаас болж БУСАД сервисүүд ДАРААЛАН унах
  • C) DB алдаа
  • D) Network алдаа

Зөв хариулт: B

Тайлбар: Teacher down → Student хүлээнэ → Student thread дуусна → Student down → Gateway timeout → Client алдаа. Домино эффект. Circuit Breaker = Cascade failure-аас хамгаалах.

Тест 37

failure-rate-threshold: 50 (Resilience4j) юу вэ?

  • A) Хурд
  • B) Сүүлийн хүсэлтүүдийн 50% АЛДААТАЙ бол Circuit Breaker → OPEN болох
  • C) Timeout
  • D) Retry тоо

Зөв хариулт: B

Тайлбар: 10 хүсэлтээс 5 нь алдаатай (50%) → OPEN. 3 алдаатай (30%) → CLOSED хэвээр. Threshold бууруулах = Илүү мэдрэмтгий. Өсгөх = Илүү тэсвэртэй.

Тест 38

wait-duration-in-open-state: 10s юу вэ?

  • A) Хүлээлтийн хугацаа
  • B) Circuit Breaker OPEN төлөвт 10 СЕКУНД хүлээж, дараа HALF-OPEN болох
  • C) Timeout
  • D) Retry хугацаа

Зөв хариулт: B

Тайлбар: OPEN = 10 сек бүх хүсэлт блоклогдоно (fallback). 10 сек дараа → HALF-OPEN → 1-3 хүсэлт оролдоно → OK бол CLOSED. Fail бол дахиад OPEN.

Тест 39

Backward Compatibility (API) яагаад чухал вэ?

  • A) Шаардлагагүй
  • B) API өөрчлөхөд ХУУЧИН CLIENT эвдрэхгүй байх — v1, v2 хувилбарлалт
  • C) Зөвхөн тест
  • D) Зөвхөн deploy

Зөв хариулт: B

Тайлбар: Student Service v1 → v2 (field нэмсэн). Хуучин client v1 ашиглаж байна. v2 = v1 field бүгд байна + шинэ field. Хуучин client эвдрэхгүй. /api/v1/students, /api/v2/students.

Тест 40

ELK Stack гэж юу вэ?

  • A) Програмчлалын хэл
  • B) Elasticsearch + Logstash + Kibana — Бүх сервисийн ЛОГИЙГ нэг газар цуглуулж, ХАЙХ, ХАРУУЛАХ
  • C) Database
  • D) Framework

Зөв хариулт: B

Тайлбар: Logstash = Лог цуглуулах. Elasticsearch = Лог хадгалах + хайх. Kibana = Dashboard. 10 сервисийн лог → Нэг газраас хайх, анализлах. Centralized logging.

Тест 41

Graceful Shutdown гэж юу вэ?

  • A) Шууд зогсоох
  • B) Сервис зогсоход ажиллаж буй ХҮСЭЛТИЙГ ДУУСГААД зогсох — Өгөгдөл алдахгүй
  • C) Force kill
  • D) Restart

Зөв хариулт: B

Тайлбар: SIGTERM → Шинэ хүсэлт хүлээхгүй → Одоо ажиллаж буй 5 хүсэлт дуусгах → Зогсох. Шууд kill хийвэл → 5 хүсэлт АЛДАГДАНА. K8s terminationGracePeriodSeconds.

Тест 42

spring.application.name: student-service юу хийдэг вэ?

  • A) DB нэр
  • B) Сервисийн НЭРИЙГ тодорхойлж, Eureka-д ЭНЭ НЭРЭЭР бүртгүүлэх
  • C) Port тохируулах
  • D) URL тохируулах

Зөв хариулт: B

Тайлбар: Eureka-д "student-service" нэрээр бүртгүүлнэ. Бусад сервис http://student-service/api/... гэж дуудна (IP биш нэрээр). Service Discovery-ийн суурь.

Тест 43

Horizontal Scaling vs Vertical Scaling-ийн ялгаа юу вэ?

  • A) Ялгаагүй
  • B) Horizontal = ОЛОН instance нэмэх, Vertical = Нэг серверийн RAM/CPU НЭМЭХ
  • C) Horizontal = RAM нэмэх
  • D) Vertical = Instance нэмэх

Зөв хариулт: B

Тайлбар: Монолит = Vertical (8GB → 32GB). Микросервис = Horizontal (Student 2 replica → 5 replica). Horizontal = Хямд, хязгааргүй. Vertical = Үнэтэй, хязгаартай.

Тест 44

Kubernetes Pod гэж юу вэ?

  • A) Сервер
  • B) НЭГ буюу ХЭДЭН container-г агуулсан K8s-ийн хамгийн ЖИЖИГ deploy нэгж
  • C) Database
  • D) Network

Зөв хариулт: B

Тайлбар: Pod = 1 Student Service container (ихэвчлэн 1 container). Replica = 2 → 2 Pod → 2 Student Service instance. K8s Pod-г автомат удирдана (restart, scale).

Тест 45

K8s Deployment гэж юу вэ?

  • A) Docker image
  • B) Pod-уудыг ХЭДЭН REPLICA ажиллуулах, ШИНЭЧЛЭХ зэргийг УДИРДАХ
  • C) Network
  • D) Volume

Зөв хариулт: B

Тайлбар: replicas: 2 = 2 Pod ажиллана. Image шинэчлэх → Rolling update. Pod crash → Автомат restart. Deployment = Pod-ийн "менежер".

Тест 46

K8s Service гэж юу вэ?

  • A) Микросервис
  • B) Pod-уудын НЭВТРЭХ ЦЭГИЙГ тодорхойлж, LOAD BALANCING хийх — DNS нэр
  • C) Docker image
  • D) Config

Зөв хариулт: B

Тайлбар: student-service:8081 = K8s DNS нэр. 2 Pod → Service автомат load balance. Pod IP өөрчлөгдсөн ч Service нэр хэвээр. K8s Service = Eureka-ийн ажлыг хийнэ.

Тест 47

livenessProbe (K8s) юу хийдэг вэ?

  • A) Pod устгах
  • B) Pod АМЬД буйг шалгаж, хариу өгөхгүй бол ДАХИН ЭХЛҮҮЛЭХ (restart)
  • C) Pod scale хийх
  • D) Pod нэрлэх

Зөв хариулт: B

Тайлбар: httpGet: /actuator/health → 3 удаа fail → Pod restart. Гацсан (frozen) апп автоматаар сэлбэгдэнэ. readinessProbe = Бэлэн эсэхийг шалгах (traffic илгээхгүй).

Тест 48

Docker Compose яагаад микросервис хөгжүүлэлтэд хэрэгтэй вэ?

  • A) Production-д
  • B) Олон сервис + DB-г ЛОКАЛ ХӨГЖҮҮЛЭЛТЭД НЭГ КОМАНДААР эхлүүлэх
  • C) Зөвхөн тест
  • D) Зөвхөн deploy

Зөв хариулт: B

Тайлбар: docker-compose up -d = Registry + Student + Teacher + Gateway + 2 DB бүгд эхэлнэ. Локал хөгжүүлэлт, интеграцийн тест. Production-д K8s ашиглана.

Тест 49

depends_on (Docker Compose) юу хийдэг вэ?

  • A) Container устгах
  • B) Container-ийн ЭХЛЭХ ДАРААЛЛЫГ тодорхойлох — Registry эхлээд → Сервисүүд
  • C) Port тохируулах
  • D) Volume нэмэх

Зөв хариулт: B

Тайлбар: student-service depends_on registry: condition: service_healthy = Registry эрүүл болсны ДАРАА Student Service эхэлнэ. Дараалал чухал (Registry эхлээд).

Тест 50

Sidecar Pattern гэж юу вэ?

  • A) Нэг container
  • B) Сервисийн ХАЖУУД нэмэлт container ажиллуулж, logging, proxy зэрэг НЭМЭЛТ ФУНКЦ хийх
  • C) Database container
  • D) Gateway container

Зөв хариулт: B

Тайлбар: Pod: [Student Service container] + [Envoy proxy sidecar]. Envoy = mTLS, retry, circuit breaker хийнэ. Student Service код ӨӨРЧЛӨХГҮЙ. Service Mesh-ийн суурь.

Тест 51

Compensation (Saga) гэж юу вэ?

  • A) Шинэ transaction
  • B) Өмнөх алхмыг БУЦААХ transaction — Student created → Payment fail → Student DELETE (rollback)
  • C) Retry
  • D) Fallback

Зөв хариулт: B

Тайлбар: Distributed = Бүхэлдээ rollback хийж ЧАДАХГҮЙ. Compensation = Алхам бүрт "буцаах" үйлдэл тодорхойлох. Create → Delete. Charge → Refund. Send → Cancel.

Тест 52

@EnableEurekaServer юу хийдэг вэ?

  • A) Client бүртгэх
  • B) Spring Boot аппыг EUREKA SERVICE REGISTRY SERVER болгох
  • C) Gateway болгох
  • D) Config Server болгох

Зөв хариулт: B

Тайлбар: @EnableEurekaServer = Port 8761-д Eureka Dashboard + Registry ажиллана. Сервисүүд энэ server-д бүртгүүлнэ. register-with-eureka: false = Өөрийгөө бүртгэхгүй.

Тест 53

Producer ба Consumer (Kafka) гэж юу вэ?

  • A) Ижил зүйл
  • B) Producer = Event ИЛГЭЭХ, Consumer = Event ХҮЛЭЭН АВАХ
  • C) Producer = Хүлээн авах
  • D) Consumer = Илгээх

Зөв хариулт: B

Тайлбар: Student Service (Producer) → kafkaTemplate.send("topic", event). Notification Service (Consumer) → @KafkaListener(topics = "topic"). Topic = Дундын "шуудангийн хайрцаг".

Тест 54

Kafka Topic гэж юу вэ?

  • A) Database table
  • B) Event-уудыг КАТЕГОРИ-аар хадгалах НЭР БҮХИЙ СҮВЭГ — "student-events", "payment-events"
  • C) API endpoint
  • D) Service нэр

Зөв хариулт: B

Тайлбар: Topic = "student-events" → StudentCreated, StudentUpdated бүгд энэ topic-д. Producer → Topic → Consumer. Topic = Логикоор ялгасан event-ийн сүвэг.

Тест 55

Consumer Group (Kafka) юу вэ?

  • A) Нэг consumer
  • B) Олон consumer-г бүлэглэж, event-г ХУВААРИЛАХ — Тус бүр өөр event боловсруулна
  • C) Producer бүлэг
  • D) Topic бүлэг

Зөв хариулт: B

Тайлбар: 3 Notification instance = 1 group. Kafka 3 event → Instance 1 (event 1), Instance 2 (event 2), Instance 3 (event 3). Давтагдахгүй, хуваарилагдана. Scale!

Тест 56

@Retry(name = "teacherService") юу хийдэг вэ?

  • A) Нэг удаа дуудах
  • B) Алдаа гарвал тодорхой тооны удаа ДАХИН ОРОЛДОХ — max-attempts: 3
  • C) Fallback
  • D) Circuit break

Зөв хариулт: B

Тайлбар: 1-р оролдлого → Fail → 1 сек хүлээх → 2-р оролдлого → Fail → 1 сек → 3-р → Fail → Circuit Breaker эсвэл fallback. Түр зуурын сүлжээний алдааг шийднэ.

Тест 57

API Versioning яагаад микросервисд чухал вэ?

  • A) Шаардлагагүй
  • B) API өөрчлөхөд ХУУЧИН CLIENT эвдрэхгүй байх — /api/v1/students, /api/v2/students
  • C) Зөвхөн дизайн
  • D) Зөвхөн тест

Зөв хариулт: B

Тайлбар: Student Service v2: response-д шинэ field нэмсэн. v1 client = Хуучин format хүлээнэ. v1 + v2 ХОЁУЛАА ажиллана. Хуучин client аажмаар v2 руу шилжинэ.

Тест 58

Centralized Logging яагаад хэрэгтэй вэ?

  • A) Шаардлагагүй
  • B) 10+ сервисийн ЛОГИЙГ НЭГ ГАЗРААС хайх, анализлах — ELK, Grafana Loki
  • C) Зөвхөн тест
  • D) Зөвхөн deploy

Зөв хариулт: B

Тайлбар: 10 сервис × 5 instance = 50 лог файл. Алдаа гарвал 50 файл нэг нэгээр шалгах уу? Centralized = Нэг газраас Correlation ID-аар хайна.

Тест 59

ClusterIP (K8s Service type) юу вэ?

  • A) Гадна хандалт
  • B) ЗӨВХӨН cluster ДОТОР хандах боломжтой — Сервис хоорондын дуудлага
  • C) Load Balancer
  • D) NodePort

Зөв хариулт: B

Тайлбар: ClusterIP = student-service:8081 cluster дотроос л хандана. Гаднаас хандахгүй. API Gateway = NodePort/LoadBalancer type → Гаднаас хандана. Дотоод сервис = ClusterIP.

Тест 60

Микросервисийг хэзээ ашиглах ХЭРЭГГҮЙ вэ?

  • A) Том төсөл
  • B) ЖИЖИГ баг, жижиг төсөл, MVP — Нарийн түвэгтэй дэд бүтэц ШААРДЛАГАГҮЙ
  • C) Их traffic
  • D) Олон баг

Зөв хариулт: B

Тайлбар: 2-3 хөгжүүлэгч + жижиг апп = Монолит хангалттай. Микросервис = Eureka, Gateway, Kafka, K8s, Monitoring → Маш их operational overhead. "Start monolith, evolve later."

Тест 61

register-with-eureka: false юу хийдэг вэ?

  • A) Бүх сервис бүртгэхгүй
  • B) Eureka SERVER ӨӨРИЙГӨӨ client-ээр бүртгэхгүй
  • C) Client бүртгэхгүй
  • D) Gateway бүртгэхгүй

Зөв хариулт: B

Тайлбар: Eureka Server = Registry. Өөрийгөө бүртгэх шаардлагагүй. register-with-eureka: false + fetch-registry: false = Зөвхөн server. Client сервисүүд = true (default).

Тест 62

RabbitMQ vs Kafka-ийн гол ялгаа юу вэ?

  • A) Ялгаагүй
  • B) RabbitMQ = MESSAGE QUEUE (нэг consumer), Kafka = EVENT STREAM (олон consumer, replay)
  • C) RabbitMQ = Event stream
  • D) Kafka = Message queue

Зөв хариулт: B

Тайлбар: RabbitMQ: Message → 1 consumer хүлээн авна → Устна. Kafka: Event → Олон consumer → Хадгалагдана (replay). RabbitMQ = Task queue. Kafka = Event streaming, analytics.

Тест 63

resources.limits (K8s) юу хийдэг вэ?

  • A) Pod тоо
  • B) Container-ийн ашиглаж болох ХАМГИЙН ИХ CPU, MEMORY-г хязгаарлах
  • C) Network хязгаар
  • D) Disk хязгаар

Зөв хариулт: B

Тайлбар: limits: memory: 512Mi, cpu: 500m = 512MB RAM, 0.5 CPU-аас илүү ашиглахгүй. Хэтэрвэл OOMKilled (memory) эсвэл throttle (CPU). Нөөц удирдлага.

Тест 64

secretKeyRef (K8s) юу хийдэг вэ?

  • A) Password кодонд бичих
  • B) K8s SECRET-аас нууц утга (DB password, JWT secret) container-д ENVIRONMENT VARIABLE-аар дамжуулах
  • C) ConfigMap
  • D) Volume

Зөв хариулт: B

Тайлбар: kubectl create secret generic db-secret --from-literal=url=jdbc:... → Deployment-д secretKeyRef → Container env-д DB_URL = нууц утга. Кодонд password БАЙХГҮЙ.

Тест 65

Loose Coupling яагаад микросервисд чухал вэ?

  • A) Шаардлагагүй
  • B) Сервисүүд бие биенээсээ ХАМААРАЛГҮЙ → Нэгийг өөрчлөхөд БУСАД нөлөөлөхгүй
  • C) Зөвхөн тест
  • D) Зөвхөн deploy

Зөв хариулт: B

Тайлбар: Student Service DB schema өөрчлөх → Teacher Service-д НӨЛӨӨЛӨХГҮЙ (API интерфейс хэвээр). Tight coupling = Нэг өөрчлөлт → 5 сервис засах. Loose = Бие даасан.

Тест 66

High Cohesion гэж юу вэ?

  • A) Олон функц
  • B) ХАМААРАЛТАЙ функцүүд НЭГ СЕРВИСТ — Student CRUD бүгд Student Service-д
  • C) Сервис холих
  • D) DB холих

Зөв хариулт: B

Тайлбар: Student create, read, update, delete = Бүгд Student Service-д. Teacher функц Student Service-д БАЙХГҮЙ. Хамааралтай зүйл → Нэг газар. Хамааралгүй → Тусдаа.

Тест 67

@CircuitBreaker(fallbackMethod = "...") юу хийдэг вэ?

  • A) Сервис эхлүүлэх
  • B) Дуудлага АЛДАА гаргахад эсвэл Circuit OPEN үед FALLBACK METHOD ажиллуулах
  • C) DB холбох
  • D) Token шалгах

Зөв хариулт: B

Тайлбар: @CircuitBreaker(name="teacher", fallbackMethod="fallback") → Teacher down → fallback(id, ex) ажиллана → Нөөц хариу буцаана. Хэрэглэгчид бүрэн алдаа харуулахгүй.

Тест 68

Микросервис архитектурт "Single Responsibility" зарчим юу вэ?

  • A) Бүгдийг нэг сервис
  • B) Сервис бүр НЭГ БИЗНЕС ЧИГ ҮҮРЭГ хариуцна — Student Service = Зөвхөн оюутан
  • C) Олон чиг үүрэг
  • D) DB хуваалт

Зөв хариулт: B

Тайлбар: Student Service = CRUD + GPA тооцоолол. Teacher Service = Багш удирдлага. Payment Service = Төлбөр. Нэг сервис олон зүйл хийвэл → "God Service" = Микросервис биш.

Тест 69

readinessProbe (K8s) юу хийдэг вэ?

  • A) Pod устгах
  • B) Pod БЭЛЭН буйг шалгаж, бэлэн биш бол TRAFFIC ИЛГЭЭХГҮЙ
  • C) Pod restart
  • D) Pod scale

Зөв хариулт: B

Тайлбар: livenessProbe = Амьд уу? (fail → restart). readinessProbe = Бэлэн үү? (fail → traffic зогсоох, restart хийхгүй). Апп эхлэх үед DB холболт хийж байна → Бэлэн биш.

Тест 70

Rolling Update (K8s) гэж юу вэ?

  • A) Бүгдийг нэг дор зогсоох
  • B) Шинэ Pod-уудыг ААЖМААР нэмж, хуучнуудыг ААЖМААР устгах — Zero downtime deploy
  • C) Бүгдийг нэг дор эхлүүлэх
  • D) Manual deploy

Зөв хариулт: B

Тайлбар: 3 Pod (v1) → 1 Pod (v2) нэмэх → 1 Pod (v1) устгах → 2 Pod (v2) нэмэх → ... Бүгд v2. Хэрэглэгч ямар ч downtime мэдрэхгүй. strategy: RollingUpdate.

Тест 71

Helm (K8s) гэж юу вэ?

  • A) Docker tool
  • B) K8s-ийн PACKAGE MANAGER — Олон YAML файлыг нэг Chart-аар удирдах
  • C) CI/CD tool
  • D) Monitoring tool

Зөв хариулт: B

Тайлбар: Student Service = Deployment + Service + ConfigMap + Secret = 4 YAML. Helm Chart = Бүгдийг нэг package-д. helm install student-service ./chart = Нэг команд. Template variable ашиглана.

Тест 72

healthcheck (Docker Compose) юу хийдэг вэ?

  • A) Container устгах
  • B) Container ЭРҮҮЛ буйг шалгаж, depends_on condition: service_healthy-д ашиглах
  • C) Image build
  • D) Volume

Зөв хариулт: B

Тайлбар: pg_isready = PostgreSQL бэлэн үү? Registry /actuator/health = Registry бэлэн үү? service_healthy = Эрүүл болсны дараа L дараагийн container эхэлнэ.

Тест 73

StripPrefix=1 (Gateway filter) юу хийдэг вэ?

  • A) Header устгах
  • B) URL PATH-ийн эхний хэсгийг хасаж, сервис рүү дамжуулах
  • C) Query parameter устгах
  • D) Body устгах

Зөв хариулт: B

Тайлбар: Client: /api/students/1 → Gateway → StripPrefix=1 → /students/1 → Student Service. Prefix хасаж, сервис дотоод path-д тохируулна. StripPrefix=0 = Хасахгүй.

Тест 74

Outbox Pattern гэж юу вэ?

  • A) Mailbox
  • B) DB transaction + Event нийтлэлтийг НАЙДВАРТАЙ зохицуулах — DB-д event хадгалаад, дараа Kafka руу
  • C) Inbox
  • D) Sent box

Зөв хариулт: B

Тайлбар: Асуудал: DB save OK → Kafka fail → Event алга! Outbox: 1) DB-д student + outbox table-д event INSERT (нэг transaction). 2) Тусдаа процесс outbox → Kafka. Найдвартай.

Тест 75

Dead Letter Queue (DLQ) гэж юу вэ?

  • A) Устгасан message
  • B) Боловсруулж ЧАДААГҮЙ message-ийг хадгалах тусгай ДАРААЛАЛ — Дараа шалгаж засах
  • C) Normal queue
  • D) Priority queue

Зөв хариулт: B

Тайлбар: Consumer event боловсруулахад алдаа → 3 retry → Fail → DLQ руу шилжих. DLQ-д хадгалагдана → Хөгжүүлэгч шалгаж, засаж, дахин боловсруулна. Event алдагдахгүй.

Тест 76

sliding-window-size: 10 (Circuit Breaker) юу вэ?

  • A) Timeout
  • B) Сүүлийн 10 ХҮСЭЛТИЙН алдааны хувийг тооцож, OPEN болох эсэхийг шийдэх
  • C) Retry тоо
  • D) Fallback тоо

Зөв хариулт: B

Тайлбар: Сүүлийн 10 хүсэлт: 8 OK + 2 fail = 20% fail → CLOSED. 5 OK + 5 fail = 50% → threshold 50% → OPEN. Цонхны хэмжээ = Хэдэн хүсэлт шалгах.

Тест 77

Canary Deployment гэж юу вэ?

  • A) Big bang deploy
  • B) Шинэ хувилбарыг БАГА хувь (5%) traffic-д ТУРШИЖ, OK бол 100% руу нэмэгдүүлэх
  • C) Rolling update
  • D) Blue-green

Зөв хариулт: B

Тайлбар: v2 deploy → 5% traffic v2 руу → Алдаа байхгүй → 25% → 50% → 100%. Алдаа байвал → 5% rollback. Эрсдэл бага. Istio, K8s-д тохируулна.

Тест 78

Blue-Green Deployment гэж юу вэ?

  • A) Canary
  • B) ХОЁР орчин (Blue=хуучин, Green=шинэ) байлгаж, traffic-г нэг дор ШИЛЖҮҮЛЭХ
  • C) Rolling update
  • D) Manual deploy

Зөв хариулт: B

Тайлбар: Blue = v1 (одоо ажиллаж байна). Green = v2 (deploy хийсэн, тест давсан). DNS/LB switch → Traffic Green руу. Алдаа → Буцааж Blue руу. Zero downtime + instant rollback.

Тест 79

@EnableEurekaClient (эсвэл автомат) юу хийдэг вэ?

  • A) Eureka Server
  • B) Spring Boot аппыг Eureka SERVER-д CLIENT-ээр БҮРТГҮҮЛЭХ
  • C) Gateway
  • D) Config Server

Зөв хариулт: B

Тайлбар: spring-cloud-starter-netflix-eureka-client dependency → Автоматаар бүртгүүлнэ. spring.application.name нэрээр. Eureka Dashboard-д харагдана. Бусад сервис олж чадна.

Тест 80

Network Latency яагаад микросервисд асуудал вэ?

  • A) Асуудал биш
  • B) Сервис хоорондын СҮЛЖЭЭНИЙ дуудлага = Нэмэлт ХУГАЦАА — Монолитид method call = 0ms
  • C) Зөвхөн DB
  • D) Зөвхөн Gateway

Зөв хариулт: B

Тайлбар: Монолит: studentService.getTeacher(id) = Нэг JVM дотор (0ms). Микросервис: HTTP call = DNS + Connection + Transfer = 1-10ms+. 10 сервис дуудвал → 10-100ms+ нэмэгдэнэ.

Тест 81

Bulkhead Pattern гэж юу вэ?

  • A) Circuit breaker
  • B) Сервис дуудлага бүрийн THREAD POOL-г ТУСГААРЛАХ — Нэг сервис удаашрахад бусадад нөлөөлөхгүй
  • C) Retry
  • D) Fallback

Зөв хариулт: B

Тайлбар: Teacher call: 10 thread. Payment call: 10 thread. Teacher удаашрах → 10 thread блоклогдоно → Payment-ийн 10 thread ЗҮГЭЭР. Bulkhead = Усан онгоцны тусгаарлагч хана.

Тест 82

Data Consistency микросервисд яагаад хэцүү вэ?

  • A) Хялбар
  • B) Сервис бүрт ТУСДАА DB → Нэг @Transactional-аар БҮГДИЙГ удирдаж ЧАДАХГҮЙ
  • C) Нэг DB
  • D) Shared DB

Зөв хариулт: B

Тайлбар: Student DB: Student created ✅. Payment DB: Payment failed ❌. Student DB дээр rollback яаж хийх? → Saga Pattern (compensation). Eventual consistency = Хожимдож нийцнэ.

Тест 83

Eventual Consistency гэж юу вэ?

  • A) Strong consistency
  • B) Бүх сервис ХОЖИМДОЖ нийцэнэ — Түр зуур зөрүүтэй байж болно
  • C) Хэзээ ч нийцэхгүй
  • D) Шууд нийцнэ

Зөв хариулт: B

Тайлбар: Student created → Event → Payment → Event → Бүгд OK = Нийцсэн. Хоромхон зуур Student = Created, Payment = Pending (зөрүүтэй). Хэсэг хугацааны дараа бүгд НИЙЦНЭ.

Тест 84

volumes (Docker Compose) яагаад хэрэгтэй вэ?

  • A) Шаардлагагүй
  • B) Container УСТГАСАН ч өгөгдлийг ХАДГАЛАХ — DB data persist
  • C) Code хадгалах
  • D) Image хадгалах

Зөв хариулт: B

Тайлбар: student-data:/var/lib/postgresql/data = DB data volume-д. docker-compose down → Container устна. Volume хэвээр → docker-compose up → Data бүрэн. -v flag → Volume ч устна.

Тест 85

Autonomous Teams зарчим юу вэ?

  • A) Нэг том баг
  • B) Баг бүр ӨӨРИЙН СЕРВИСИЙГ бүтнээр хариуцна — Код, тест, deploy, мониторинг
  • C) Хуваарилсан хариуцлага
  • D) Зөвхөн код

Зөв хариулт: B

Тайлбар: Student Team = Student Service-ийн код, тест, CI/CD, deploy, мониторинг. Бусад багаас хамааралгүй шийдвэр гаргана. Conway's Law: Системийн бүтэц = Байгууллагын бүтэц.

Тест 86

spring.cloud.gateway.routes юу тохируулдаг вэ?

  • A) Database
  • B) URL PATTERN-аар хүсэлтийг ЗӨВ СЕРВИС рүү чиглүүлэх ДҮРЭМ
  • C) Auth
  • D) Logging

Зөв хариулт: B

Тайлбар: Path=/api/students/**uri: lb://student-service. /api/teachers/**lb://teacher-service. Route = Predicates (condition) + URI (destination) + Filters.

Тест 87

12-Factor App гэж юу вэ?

  • A) 12 сервис
  • B) Cloud-native апп бичих 12 ЗАРЧИМ — Config, Logs, Port binding, Stateless зэрэг
  • C) 12 баг
  • D) 12 DB

Зөв хариулт: B

Тайлбар: III. Config = Environment variable. VI. Processes = Stateless. VII. Port binding = Өөрөө port нээх. XI. Logs = stdout. Микросервис = 12-factor зарчимд нийцтэй.

Тест 88

environment (Docker Compose) юу хийдэг вэ?

  • A) Image build
  • B) Container-д ENVIRONMENT VARIABLE дамжуулах — DB_URL, API_KEY
  • C) Volume
  • D) Port

Зөв хариулт: B

Тайлбар: SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/studentdb → Container дотор application.yml-д ашиглана. Кодонд password ХАРДКОДЛОХГҮЙ. 12-Factor: Config = Env var.

Тест 89

API Contract гэж юу вэ?

  • A) Хууль
  • B) Сервис хоорондын API-ийн ТОХИРОЛЦСОН FORMAT — Request/Response schema, status code
  • C) DB schema
  • D) UI дизайн

Зөв хариулт: B

Тайлбар: Student Service ↔ Teacher Service: "GET /api/teachers/{id} → TeacherResponse {id, name, department}". Contract өөрчлөхөд → Consumer-д мэдэгдэх. Contract testing (Pact).

Тест 90

Timeout тохируулах яагаад чухал вэ?

  • A) Шаардлагагүй
  • B) Хариу ирэхгүй сервисийг ХЯЗГААРТАЙ хүлээж, thread БЛОКЛОГДОХООС хамгаалах
  • C) Зөвхөн тест
  • D) Зөвхөн deploy

Зөв хариулт: B

Тайлбар: Timeout байхгүй → Teacher Service хариу өгөхгүй → Student thread МӨНХӨД хүлээнэ → Thread бүгд дуусна → Student Service ч ЗОГСОНО. Timeout 3 сек → 3 сек дараа fallback.

Тест 91

Prometheus + Grafana юу хийдэг вэ?

  • A) CI/CD
  • B) Сервисийн МЕТРИК цуглуулж (Prometheus), DASHBOARD-аар харуулах (Grafana)
  • C) Message broker
  • D) Service registry

Зөв хариулт: B

Тайлбар: Prometheus: CPU, memory, request count, response time цуглуулна. Grafana: Dashboard, graph, alert. "Student Service response time > 2 сек" → Alert → Шалгах.

Тест 92

Back Pressure гэж юу вэ?

  • A) Хурдасгах
  • B) Consumer БОЛОВСРУУЛЖ АМЖИХГҮЙ байхад Producer-ийг УДААШРУУЛАХ эсвэл зогсоох
  • C) Fallback
  • D) Retry

Зөв хариулт: B

Тайлбар: Producer 1000 event/сек → Consumer 100 event/сек → Queue дүүрнэ → Memory exhaustion. Back pressure: Queue хязгаар → Producer удаашрах. Kafka: Consumer pull model = Өөрийн хурдаар.

Тест 93

replicas: 2 (K8s Deployment) юу вэ?

  • A) 2 сервис
  • B) Сервисийн 2 INSTANCE (Pod) ажиллуулах — High availability, load balancing
  • C) 2 DB
  • D) 2 container

Зөв хариулт: B

Тайлбар: 2 Pod = 1 Pod crash → Бусад 1 Pod хариу өгнө (downtime байхгүй). Load balance = 2 Pod-д тэнцүү хуваарилна. Traffic ихсэвэл → replicas: 5.

Тест 94

Conway's Law гэж юу вэ?

  • A) Програмчлалын хууль
  • B) Системийн БҮТЭЦ = Байгууллагын БҮТЭЦ-ийг дагана
  • C) Database хууль
  • D) Network хууль

Зөв хариулт: B

Тайлбар: 3 баг = 3 сервис. 1 баг = 1 монолит. Микросервис = Жижиг бие даасан баг бүр өөрийн сервис. Байгууллагын бүтэц → Системийн архитектурт нөлөөлнө.

Тест 95

Distributed Lock яагаад хэрэгтэй вэ?

  • A) Шаардлагагүй
  • B) Олон instance НЭГ нөөцийг ЗЭРЭГ өөрчлөхөөс хамгаалах — Redis Lock
  • C) Зөвхөн DB
  • D) Зөвхөн файл

Зөв хариулт: B

Тайлбар: 2 Student Service instance → 2-уулаа ижил student update → Race condition! Redis Lock: Instance 1 lock авна → Update → Unlock. Instance 2 хүлээнэ. Consistent.

Тест 96

Feature Flag гэж юу вэ?

  • A) Git branch
  • B) Шинэ функцийг КОД DEPLOY хийсэн ч ИДЭВХГҮЙ байлгаж, тохиргоогоор АСААХ/УНТРААХ
  • C) Bug fix
  • D) Hotfix

Зөв хариулт: B

Тайлбар: if (featureFlags.isEnabled("new-grading")) { newGrading(); } else { oldGrading(); }. Deploy хийсэн ч flag = off → Хуучин ажиллана. flag = on → Шинэ. Эрсдэлгүй deploy.

Тест 97

Observability-ийн 3 тулгуур юу вэ?

  • A) Code, Test, Deploy
  • B) LOGS (лог), METRICS (хэмжүүр), TRACES (хянах) — Системийн төлвийг ойлгох
  • C) CPU, RAM, Disk
  • D) Auth, CORS, CSRF

Зөв хариулт: B

Тайлбар: Logs = Юу болсон? (ELK). Metrics = Хэр их, хэр хурдан? (Prometheus). Traces = Хаана удааширсан? (Zipkin). 3-уулаа байж → Систем бүрэн хянагдана.

Тест 98

Circuit Breaker vs Retry-ийн ялгаа юу вэ?

  • A) Ялгаагүй
  • B) Retry = Алдаа гарвал ДАХИН ОРОЛДОХ, Circuit Breaker = Олон алдаа гарвал БҮРЭН ЗОГСООХ
  • C) Retry = Зогсоох
  • D) Circuit Breaker = Оролдох

Зөв хариулт: B

Тайлбар: Retry (3 удаа) → Бүгд fail → Circuit Breaker OPEN → Fallback. Retry = Түр зуурын алдаа шийднэ. Circuit Breaker = Удаан хугацааны алдааг ЗОГСООНО. Хамтдаа ашиглана.

Тест 99

Микросервисийн хамгийн чухал зарчим юу вэ?

  • A) Олон сервис
  • B) Сервис бүр БИЕ ДААСАН deploy, scale, develop хийж чадах — Loose coupling + High cohesion
  • C) Олон DB
  • D) Олон баг

Зөв хариулт: B

Тайлбар: Бие даасан = Нэг сервис өөрчлөхөд бусдад нөлөөлөхгүй. Deploy: Student v2 → Teacher хэвээр. Scale: Student 5 instance → Teacher 2 хэвээр. Энэ бол микросервисийн ЦӨМИЙН утга.

Тест 100

"Start with monolith, evolve to microservices" гэж юу вэ?

  • A) Микросервисээр эхлэх
  • B) МОНОЛИТООР эхэлж, шаардлагатай болоход микросервис рүү ААЖМААР шилжих
  • C) Бүгдийг нэг дор шилжих
  • D) Хэзээ ч шилжихгүй

Зөв хариулт: B

Тайлбар: Эхнээс микросервис = Over-engineering. Монолит → Хурдан эхлэх → Бизнес ургах → Bottleneck олох → Strangler Fig Pattern → Аажмаар микросервис. Martin Fowler: "MonolithFirst."


📚 Ашигласан эх сурвалжууд:

  • Sam Newman — Building Microservices, 2nd Edition (O'Reilly, 2021)
  • Chris Richardson — Microservices Patterns (Manning, 2018)
  • Martin Fowler — Microservices (martinfowler.com/articles/microservices.html)
  • Spring Cloud Documentation (spring.io/projects/spring-cloud)
  • Kubernetes Documentation (kubernetes.io/docs)
  • Apache Kafka Documentation (kafka.apache.org)
  • Netflix OSS — Eureka, Zuul, Hystrix (github.com/Netflix)
  • Resilience4j Documentation (resilience4j.readme.io)