Microservices Architecture
Back to Software Development Index
What is a Service?
Service คือซอฟต์แวร์ ที่ทำงานโดยไม่ขึ้นกับกัน (independently deployable) มีขอบเขตการทำงานที่ชัดเจน
Key Characteristics:
- Independently deployable - Deploy ได้โดยไม่กระทบระบบอื่น
- Loosely coupled - ไม่ผูกติดกันมาก สามารถเปลี่ยนแปลงได้
- Business capability focused - แต่ละ service ทำงานตาม business function
- Owns its data - แต่ละ service มี database ของตัวเอง
Why Microservices?
✅ Benefits
1. Independent Deployment
- Deploy service ใด service หนึ่งโดยไม่ต้อง deploy ทั้งระบบ
- ลด downtime และ risk
2. Technology Diversity
- แต่ละ service เลือกเทคโนโลยีที่เหมาะสมได้
- ง่ายต่อการทดลองเทคโนโลยีใหม่
3. Scalability
- Scale เฉพาะ service ที่มี load สูง
- ประหยัดทรัพยากร
4. Team Autonomy
- แต่ละทีมดูแล service ของตัวเอง
- ทำงานได้เร็วขึ้น ลดการรอคอย
5. Resilience
- Service หนึ่งล่มไม่กระทบทั้งระบบ
- Isolate failures
6. Easier to Understand
- แต่ละ service เล็ก เข้าใจง่าย
- Onboard developer ใหม่เร็วขึ้น
❌ Challenges
1. Increased Complexity
- Distributed system ซับซ้อนกว่า monolith
- ต้องจัดการ inter-service communication
2. Operational Overhead
- ต้อง deploy, monitor หลาย services
- ต้องการ DevOps, automation
3. Data Consistency
- ไม่มี transaction ข้าม services
- ต้องใช้ eventual consistency
4. Testing Complexity
- Integration testing ยากขึ้น
- ต้อง test การทำงานร่วมกันของหลาย services
5. Network Latency
- การเรียกผ่าน network ช้ากว่า in-memory
- ต้อง optimize communication
6. Debugging Difficulty
- Error อาจเกิดจากหลาย services
- ต้องมี distributed tracing
When to Use Microservices?
Use Microservices When: ✅
- Large, complex applications
- Multiple teams working on different areas
- Need independent deployment cycles
- Different scalability requirements per module
- Long-term project (years)
- Team has DevOps expertise
Stick with Monolith When: ❌
- Small applications
- Small team (< 10 developers)
- Tight deadlines
- Limited DevOps resources
- Unclear requirements
- Startup/MVP phase
Remember: Start with monolith, move to microservices when needed
Domain-Driven Design & Bounded Context
ใช้ DDD ในการแบ่ง microservices:
Bounded Context:
- แต่ละ context คือ 1 service (โดยทั่วไป)
- มี ubiquitous language ของตัวเอง
- มี database ของตัวเอง
Example: E-commerce
┌─────────────────┐ ┌─────────────────┐
│ Order Service │ │ Payment Service │
│ │ │ │
│ - Order │ │ - Transaction │
│ - OrderItem │ │ - PaymentMethod │
│ - Customer │ │ - Receipt │
└─────────────────┘ └─────────────────┘
┌─────────────────┐ ┌─────────────────┐
│ Product Service │ │ Shipping Service│
│ │ │ │
│ - Product │ │ - Shipment │
│ - Category │ │ - Tracking │
│ - Inventory │ │ - Carrier │
└─────────────────┘ └─────────────────┘
Same Entity, Different Context:
- “Customer” in Order Service → Order history, preferences
- “Customer” in Payment Service → Payment methods, billing address
- “Customer” in Shipping Service → Delivery addresses
Microservices Patterns
1. Load Balancer Pattern
┌─────────────┐
│Load Balancer│
└──────┬──────┘
┌───────┼───────┐
│ │ │
┌───▼──┐ ┌──▼──┐ ┌─▼───┐
│Srv 1 │ │Srv 2│ │Srv 3│
└──────┘ └─────┘ └─────┘
- กระจาย traffic ไปยังหลาย instances
- เพิ่ม availability และ throughput
- Tools: Nginx, HAProxy, AWS ELB
2. API Composition Pattern
┌─────────┐
│ Client │
└────┬────┘
│
┌────▼────────┐
│ API Gateway │
└────┬────────┘
│
┌─────┼─────┐
│ │ │
┌──▼─┐ ┌─▼─┐ ┌▼──┐
│Srv1│ │Sv2│ │Sv3│
└────┘ └───┘ └───┘
- API Gateway รวม data จากหลาย services
- Client ติดต่อจุดเดียว
- Examples: User profile = User Service + Order Service + Review Service
3. SAGA Pattern
จัดการ distributed transactions โดยไม่ใช้ 2-phase commit
Choreography-based SAGA:
Order → Payment → Inventory → Shipping
↓ ↓ ↓ ↓
Events Events Events Events
- แต่ละ service publish event
- Service อื่นๆ subscribe และทำงานต่อ
- ถ้าล้ม ทำ compensating transaction
Orchestration-based SAGA:
┌──────────────┐
│ SAGA Manager │
└──────┬───────┘
┌───────┼───────┐
│ │ │
┌──▼─┐ ┌─▼──┐ ┌─▼──┐
│Ord │ │Pay │ │Inv │
└────┘ └────┘ └────┘
- Central orchestrator จัดการ flow
- ง่ายต่อการ monitor และ debug
4. Event Sourcing
เก็บทุก event ที่เกิดขึ้นในระบบ แทนที่จะเก็บแค่ state ปัจจุบัน
Benefits:
- Audit trail เต็มรูปแบบ
- Time travel - ย้อนดู state ในอดีต
- Event replay - Rebuild state ใหม่ได้
Example:
Events:
1. AccountCreated(userId: 1, balance: 0)
2. MoneyDeposited(userId: 1, amount: 1000)
3. MoneyWithdrawn(userId: 1, amount: 500)
Current State: balance = 500
5. CQRS (Command Query Responsibility Segregation)
แยก model สำหรับ read และ write
┌──────────────────┐
│ Command Side │ Write Model
│ (Write DB) │ Optimized for updates
└────────┬─────────┘
│ Events
▼
┌──────────────────┐
│ Query Side │ Read Model
│ (Read DB) │ Optimized for queries
└──────────────────┘
Benefits:
- Optimize แยกกันได้
- Scale read/write แยกกัน
- ใช้ database ต่างกันได้
When to Use:
- Read และ write patterns ต่างกันมาก
- ต้องการ scale read/write แยกกัน
- ต้องการ read model หลายแบบ
Handling Failures
Circuit Breaker Pattern
┌──────────┐
│ Closed │ ──fail──> ┌──────────┐
│ (Normal) │ │ Open │
└────┬─────┘ │(Blocking)│
│ └────┬─────┘
│ │
│ timeout
│ │
│ ┌────▼─────┐
└────success─────│Half-Open │
│ (Testing)│
└──────────┘
States:
- Closed: Normal, requests go through
- Open: Too many failures, block requests
- Half-Open: Try again after timeout
Benefits:
- Prevent cascading failures
- Fast failure
- Automatic recovery
Tools: Hystrix, Resilience4j, Polly
Retry with Exponential Backoff
func RetryWithBackoff(fn func() error, maxRetries int) error {
for i := 0; i < maxRetries; i++ {
err := fn()
if err == nil {
return nil
}
if i == maxRetries-1 {
return err
}
// Exponential backoff: 1s, 2s, 4s, 8s...
time.Sleep(time.Duration(1<<i) * time.Second)
}
return nil
}Timeout Pattern
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
resp, err := client.Get(ctx, "http://service/api")
if err != nil {
// Handle timeout
}Scaling Strategies
Horizontal Scaling (Scale Out)
เพิ่มจำนวน instances:
1 instance -> 2 instances -> 4 instances
Pros: ✅
- Unlimited scaling (theoretically)
- High availability
- Easy with cloud
Cons: ❌
- Need load balancer
- Stateless design required
- More complex
Vertical Scaling (Scale Up)
เพิ่ม resources (CPU, RAM):
2 CPU, 4GB -> 4 CPU, 8GB -> 8 CPU, 16GB
Pros: ✅
- Simple
- No code changes
- Works with stateful apps
Cons: ❌
- Limited by hardware
- Single point of failure
- More expensive
Auto Scaling
# Kubernetes HPA example
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-service
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-service
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70Database Strategies
1. Database per Service
แต่ละ service มี database ของตัวเอง:
Service A ──> Database A
Service B ──> Database B
Service C ──> Database C
Pros: ✅
- Loose coupling
- Independent scaling
- Technology diversity
Cons: ❌
- No cross-service transactions
- Data duplication
- Complex queries
2. Shared Database (Anti-pattern)
หลาย services ใช้ database เดียวกัน:
Service A ──┐
Service B ──┼──> Shared Database
Service C ──┘
Why Avoid:
- Tight coupling
- Schema changes affect all
- Hard to scale independently
- Breaks microservices principles
3. Saga Pattern for Consistency
ใช้ distributed transactions แทน ACID:
Order Service: Create Order
↓ (success)
Payment Service: Process Payment
↓ (success)
Inventory Service: Reserve Items
↓ (failure)
Payment Service: Refund
↓
Order Service: Cancel Order
Communication Patterns
Synchronous (REST, gRPC)
Client ──request──> Service A ──request──> Service B
<─response── <─response──
Pros: ✅ Simple, immediate response Cons: ❌ Tight coupling, cascading failures
Asynchronous (Message Queue)
Service A ──> [Queue] ──> Service B
↓
Service C
Pros: ✅ Loose coupling, resilient Cons: ❌ Complex, eventual consistency
Tools: RabbitMQ, Kafka, AWS SQS
Testing Microservices
Testing pyramid สำหรับ microservices:
╱╲
╱E2E╲ ← Fewest, most expensive
╱──────╲
╱Contract╲ ← API contracts between services
╱──────────╲
╱Integration╲ ← Test service integration
╱──────────────╲
╱ Unit Tests ╲ ← Most, cheapest
╱────────────────╲
Contract Testing
ทำให้มั่นใจว่า services พูดคุยกันได้:
Consumer ←─ Contract ─→ Provider
Test Test
Tools: Pact, Spring Cloud Contract
Related:
References: