簡介
「微服務」是軟體架構中最熱門的流行詞。但從微服務開始往往是個錯誤。本文分析何時使用哪種架構,以及如何安全遷移。
1.整體架構
1.1 什麼是單體架構?
┌─────────────────────────────────────────┐
│ Monolith Application │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐│
│ │ User │ │ Order │ │ Payment ││
│ │ Module │ │ Module │ │ Module ││
│ └────┬─────┘ └────┬─────┘ └────┬─────┘│
│ │ │ │ │
│ ┌────▼────────────▼────────────▼─────┐ │
│ │ Shared Database │ │
│ └────────────────────────────────────┘ │
│ │
│ 1 deployable unit │
│ 1 process │
│ 1 database │
└─────────────────────────────────────────┘
1.2 優點和缺點
Ưu điểm:
✅ Simple development & debugging
✅ Simple testing (1 app)
✅ Simple deployment (1 artifact)
✅ No network overhead (function calls)
✅ ACID transactions dễ dàng
✅ Phù hợp team nhỏ (< 10 devs)
Nhược điểm:
❌ Code base lớn → khó hiểu
❌ Build/deploy chậm
❌ Scale phải scale TOÀN BỘ app
❌ Technology lock-in (1 language/framework)
❌ 1 module crash → toàn bộ app crash
❌ Team lớn → merge conflicts, coordination overhead
2. 模組化整體架構
┌─────────────────────────────────────────────┐
│ Modular Monolith │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ User │ │ Order │ │ Payment │ │
│ │ Module │ │ Module │ │ Module │ │
│ │ │ │ │ │ │ │
│ │ Public │ │ Public │ │ Public │ │
│ │ API only │ │ API only │ │ API only │ │
│ │ │ │ │ │ │ │
│ │ Private │ │ Private │ │ Private │ │
│ │ DB schema│ │ DB schema│ │ DB schema│ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ 1 deployable, nhưng modules tách biệt │
│ Module giao tiếp qua PUBLIC interfaces │
│ Không shared database tables │
└─────────────────────────────────────────────┘
→ 80% benefits của Microservices
→ 20% complexity
→ Best starting point cho hầu hết projects
3.微服務架構
3.1 原則
1. Single Responsibility:
Mỗi service làm 1 việc, làm tốt
2. Bounded Context (DDD):
Mỗi service sở hữu domain riêng
e.g., "Order" trong Order Service ≠ "Order" trong Shipping
3. Independently Deployable:
Deploy service A mà không ảnh hưởng service B
4. Decentralized Data Management:
Mỗi service có database riêng
KHÔNG shared database!
5. Design for Failure:
Assume services WILL fail
Circuit breakers, retries, fallbacks
6. Smart Endpoints, Dumb Pipes:
Logic trong services, không trong message bus
3.2 架構
API Gateway
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ User │ │ Order │ │ Payment │
│ Service │ │ Service │ │ Service │
│ │ │ │ │ │
│ REST API │ │ REST API │ │ gRPC API │
│ │ │ │ │ │
│ Own DB │ │ Own DB │ │ Own DB │
│(Postgres)│ │(MongoDB) │ │(Postgres)│
└──────────┘ └──────────┘ └──────────┘
│ │ │
└───────────────┼───────────────┘
│
Message Bus
(Kafka/RabbitMQ)
4. 何時不使用微服務
❌ Team < 10 developers
❌ Startup giai đoạn đầu (chưa rõ domain boundaries)
❌ Simple CRUD application
❌ Không có DevOps maturity (CI/CD, monitoring, container)
❌ Team chưa có kinh nghiệm distributed systems
❌ Tight deadline, cần ship nhanh
Microservices Tax:
- Network latency giữa services
- Distributed transactions (phức tạp!)
- Service discovery, load balancing
- Distributed tracing, centralized logging
- Container orchestration (K8s)
- Data consistency challenges
- Testing complexity (integration tests)
→ Nếu team < 5 người, chi phí này > lợi ích
5. 遷移:絞殺者無花果圖案
5.1 概念
Giống cây sung bóp nghẹt (strangler fig):
Cây mới mọc BỌC QUANH cây cũ
Dần dần thay thế
Cây cũ chết, cây mới đứng vững
Phase 1: Monolith + New Service
┌──────────────────────┐
│ API Gateway/Proxy │
└──────┬───────────────┘
│
┌────▼────┐ ┌──────────┐
│Monolith │ │ New User │
│(all) │ │ Service │
└─────────┘ └──────────┘
/api/users → New Service
/api/* → Monolith
Phase 2: More Services
┌──────────────────────┐
│ API Gateway/Proxy │
└──────┬───────────────┘
│
┌────▼────┐ ┌──────────┐ ┌──────────┐
│Monolith │ │ User │ │ Order │
│(shrink) │ │ Service │ │ Service │
└─────────┘ └──────────┘ └──────────┘
Phase 3: Monolith eliminated
┌──────────────────────┐
│ API Gateway │
└──────┬───────────────┘
│
┌──────▼──┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ User │ │ Order │ │Payment │ │Inventory│
│Service │ │ Service │ │Service │ │Service │
└────────┘ └─────────┘ └─────────┘ └─────────┘
5.2 步驟
1. Identify Boundaries:
DDD → Bounded Contexts → Service boundaries
Tìm module ÍT coupling nhất → Extract trước
2. Build Proxy:
Đặt API Gateway/Proxy trước Monolith
Route traffic theo path
3. Extract Service:
a) Copy code sang service mới
b) Tạo database riêng
c) Migrate data
d) Route traffic → new service
e) Remove old code từ monolith
4. Repeat:
Extract tiếp service khác
Monolith thu nhỏ dần
6. 服務分解策略
1. By Business Capability:
Marketing → Marketing Service
Sales → Sales Service
Fulfillment → Fulfillment Service
2. By Subdomain (DDD):
Core domain → Core services (in-house)
Supporting domain → Supporting services
Generic domain → Buy/SaaS (auth, email, payment)
3. By Data Ownership:
User data → User Service
Product data → Catalog Service
Order data → Order Service
4. By Team:
Team A owns Service A
Team B owns Service B
Conway's Law: System mirrors org structure
對比總結
| 標準 | 巨石 | 模組化整體 | 微服務 |
|---|---|---|---|
| 複雜性 | 低 | 中 | 高 |
| 部署 | 簡單 | 簡單 | 複雜 |
| 縮放 | 垂直 | 垂直 | 水平/服務 |
| 技術多樣性 | 單疊 | 單疊 | 多語言 |
| 團隊規模 | 1-15 | 1-15 5-30 | 20+ |
| 資料一致性 | 酸性 | 酸性 | 最終 |
| 推薦入手 | ✅ | ✅✅ | ❌ |
練習
-
架構決策: 金融科技新創公司,6 名開發人員團隊,MVP 需要在 3 個月內交付。功能:用戶身份驗證、錢包、交易、KYC。選擇整體式、模組化整體式還是微服務?解釋。
-
Strangler Fig 計劃: Monolith 電子商務(15 名開發人員)具有模組:身份驗證、用戶、產品、訂單、付款、庫存、通知、分析。寫遷移計畫:首先要提取哪個服務,為什麼?
-
有界上下文: 「產品」一詞在目錄(名稱、描述、圖像)、庫存(庫存、倉庫)、定價(成本、折扣、利潤)中具有不同的意義。繪製有界上下文圖。