- Translated and revised architecture documents to enhance clarity and accessibility for both English and Vietnamese audiences. - Improved diagrams and descriptions for caching, data consistency, event-driven architecture, microservices communication, observability, and security architecture. - Ensured consistent formatting and terminology across all documents to facilitate better understanding and navigation. - Added quick tips and troubleshooting sections to assist developers in implementing and managing the architecture effectively.
508 lines
16 KiB
Markdown
508 lines
16 KiB
Markdown
# Kiến trúc Giao tiếp Microservices
|
|
|
|
> Các patterns và protocols giao tiếp giữa các services
|
|
|
|
## Quick Overview
|
|
|
|
Hướng dẫn nhanh về các patterns giao tiếp cơ bản trong hệ thống GoodGo.
|
|
|
|
### Mô hình Giao tiếp Cơ bản
|
|
|
|
```mermaid
|
|
graph TD
|
|
%% Nodes
|
|
Client[Web App / Mobile App]
|
|
Traefik[Traefik API Gateway]
|
|
Auth[Auth Service]
|
|
Notify[Notification Service]
|
|
|
|
%% Relationships
|
|
Client -->|HTTP Request| Traefik
|
|
Traefik -->|Routing| Auth
|
|
Auth -.->|Internal HTTP| Notify
|
|
|
|
%% Styles using dark color palette
|
|
style Client fill:#1565c0,stroke:#fff,stroke-width:2px,color:#fff
|
|
style Traefik fill:#0f4c81,stroke:#fff,stroke-width:2px,color:#fff
|
|
style Auth fill:#283593,stroke:#fff,stroke-width:2px,color:#fff
|
|
style Notify fill:#4527a0,stroke:#fff,stroke-width:2px,color:#fff
|
|
```
|
|
|
|
### Giao tiếp Đồng bộ (HTTP/REST)
|
|
|
|
Các service giao tiếp đồng bộ qua HTTP REST APIs thông qua Traefik API Gateway.
|
|
|
|
**Ví dụ Client → Service:**
|
|
```typescript
|
|
// Web App -> Auth Service
|
|
const response = await fetch('http://api.goodgo.vn/api/v1/auth/login', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ email, password }),
|
|
});
|
|
```
|
|
|
|
**Ví dụ Service → Service:**
|
|
```typescript
|
|
// Auth Service -> Notification Service
|
|
const response = await fetch('http://notification-service:5003/api/v1/notifications', {
|
|
method: 'POST',
|
|
headers: { 'X-Service-Auth': process.env.INTERNAL_API_KEY },
|
|
body: JSON.stringify({ userId, message }),
|
|
});
|
|
```
|
|
|
|
### API Gateway Routing
|
|
|
|
Traefik định tuyến requests dựa trên:
|
|
- **Host header**: `api.goodgo.vn`
|
|
- **Path prefix**: `/api/v1/auth`, `/api/v1/users`
|
|
|
|
### Format Error Response Chuẩn
|
|
|
|
Tất cả services tuân theo định dạng error response nhất quán:
|
|
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": {
|
|
"code": "AUTH_001",
|
|
"message": "Invalid credentials",
|
|
"details": {}
|
|
},
|
|
"timestamp": "2024-01-01T00:00:00.000Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Sơ đồ Tổng quan
|
|
|
|
```mermaid
|
|
graph TD
|
|
Client[Client Apps] --> Gateway[API Gateway<br/>Traefik]
|
|
|
|
Gateway --> ServiceA[Service A]
|
|
Gateway --> ServiceB[Service B]
|
|
|
|
ServiceA <-->|REST/HTTP| ServiceB
|
|
ServiceA -->|Events| Kafka[Kafka Broker]
|
|
ServiceB <-.->|Sub| Kafka
|
|
|
|
ServiceA --> SD[Service Discovery<br/>Docker DNS / K8s DNS]
|
|
ServiceB --> SD
|
|
|
|
classDef blue fill:#253041,stroke:#4b6584,color:#ffffff
|
|
classDef orange fill:#3a2e1e,stroke:#7a5f3c,color:#ffffff
|
|
classDef green fill:#1e3a29,stroke:#3c7a52,color:#ffffff
|
|
|
|
class Gateway blue
|
|
class Kafka orange
|
|
class SD green
|
|
```
|
|
|
|
## Bối cảnh Hệ thống
|
|
|
|
```mermaid
|
|
C4Context
|
|
title System Context Diagram for GoodGo Microservices Communication
|
|
|
|
Person(client_web, "Web Client", "Browser/Mobile App")
|
|
Person(client_api, "API Consumer", "External API clients")
|
|
|
|
System_Boundary(goodgo, "GoodGo Platform") {
|
|
System(gateway, "API Gateway", "Traefik - Routes requests to services")
|
|
System(services, "Microservices", "IAM, User, Order, Product services")
|
|
System(kafka, "Event Bus", "Kafka - Async communication")
|
|
System(discovery, "Service Discovery", "Docker DNS / K8s DNS")
|
|
}
|
|
|
|
System_Ext(db, "Database", "Neon PostgreSQL")
|
|
System_Ext(cache, "Cache", "Redis")
|
|
System_Ext(external_api, "External APIs", "Payment, Email, SMS")
|
|
|
|
Rel(client_web, gateway, "Uses", "HTTPS")
|
|
Rel(client_api, gateway, "Calls", "HTTPS/REST")
|
|
Rel(gateway, services, "Routes to", "HTTP")
|
|
Rel(services, kafka, "Pub/Sub", "Kafka Protocol")
|
|
Rel(services, discovery, "Lookup", "DNS")
|
|
Rel(services, db, "Reads/Writes", "PostgreSQL")
|
|
Rel(services, cache, "Gets/Sets", "Redis Protocol")
|
|
Rel(services, external_api, "Integrates", "HTTPS")
|
|
```
|
|
|
|
Nền tảng GoodGo sử dụng kiến trúc microservices nơi tất cả client requests đi qua API Gateway (Traefik), được route đến các microservices phù hợp. Các services giao tiếp đồng bộ qua REST/HTTP cho patterns request-response và bất đồng bộ qua Kafka cho workflows event-driven. Service discovery được xử lý bởi Docker DNS trong môi trường local và Kubernetes DNS trong production.
|
|
|
|
## Protocols Giao tiếp
|
|
|
|
### So sánh Protocols
|
|
|
|
| Protocol | Latency | Complexity | Use Case |
|
|
|----------|---------|------------|----------|
|
|
| **REST** | Medium | Low | External APIs, CRUD |
|
|
| **gRPC** | Low | High | Internal high-performance |
|
|
| **Events** | Async | Medium | Decoupled workflows |
|
|
| **GraphQL** | Medium | Medium | Complex data fetching |
|
|
|
|
### Pattern REST/HTTP
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Client
|
|
participant Gateway as API Gateway
|
|
participant ServiceA as Service A
|
|
participant ServiceB as Service B
|
|
|
|
Client->>Gateway: GET /api/v1/users/123
|
|
Gateway->>ServiceA: Forward Request
|
|
ServiceA->>ServiceB: GET /internal/permissions/123
|
|
ServiceB-->>ServiceA: Permissions
|
|
ServiceA-->>Gateway: User + Permissions
|
|
Gateway-->>Client: JSON Response
|
|
```
|
|
|
|
Request-response đồng bộ sử dụng HTTP/REST.
|
|
|
|
**Triển khai (.NET với IHttpClientFactory)**:
|
|
```csharp
|
|
// EN: Service-to-service HTTP client
|
|
// VI: HTTP client cho giao tiếp giữa services
|
|
public class IamServiceClient : IIamServiceClient
|
|
{
|
|
private readonly HttpClient _httpClient;
|
|
private readonly ILogger<IamServiceClient> _logger;
|
|
|
|
public IamServiceClient(HttpClient httpClient, ILogger<IamServiceClient> logger)
|
|
{
|
|
_httpClient = httpClient;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<UserDto?> GetUserAsync(Guid userId, CancellationToken ct)
|
|
{
|
|
try
|
|
{
|
|
var response = await _httpClient.GetAsync($"/api/v1/users/{userId}", ct);
|
|
response.EnsureSuccessStatusCode();
|
|
|
|
return await response.Content.ReadFromJsonAsync<UserDto>(ct);
|
|
}
|
|
catch (HttpRequestException ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to get user {UserId}", userId);
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
|
|
// EN: Registration in Program.cs
|
|
// VI: Đăng ký trong Program.cs
|
|
builder.Services.AddHttpClient<IIamServiceClient, IamServiceClient>(client =>
|
|
{
|
|
client.BaseAddress = new Uri("http://iam-service-net:8080");
|
|
client.DefaultRequestHeaders.Add("X-Service-Name", "storage-service");
|
|
client.Timeout = TimeSpan.FromSeconds(5);
|
|
})
|
|
.AddPolicyHandler(GetRetryPolicy())
|
|
.AddPolicyHandler(GetCircuitBreakerPolicy());
|
|
```
|
|
|
|
### Pattern Event-Driven
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant ServiceA
|
|
participant Kafka
|
|
participant ServiceB
|
|
participant ServiceC
|
|
|
|
ServiceA->>Kafka: Publish: user.created
|
|
Kafka->>ServiceB: Deliver event
|
|
Kafka->>ServiceC: Deliver event
|
|
|
|
par Parallel Processing
|
|
ServiceB->>ServiceB: Send welcome email
|
|
ServiceC->>ServiceC: Create user profile
|
|
end
|
|
```
|
|
|
|
Giao tiếp bất đồng bộ dựa trên events qua Kafka.
|
|
|
|
### Khám phá Dịch vụ
|
|
|
|
**Local (Docker Compose)**:
|
|
```yaml
|
|
# Services discover via Docker DNS
|
|
http://service-name:port
|
|
http://iam-service:3001
|
|
```
|
|
|
|
**Kubernetes**:
|
|
```yaml
|
|
# Services discover via K8s DNS
|
|
http://service-name.namespace.svc.cluster.local
|
|
http://iam-service.default.svc.cluster.local:3001
|
|
```
|
|
|
|
## Pattern API Gateway
|
|
|
|
```mermaid
|
|
graph LR
|
|
Client --> Gateway[API Gateway<br/>Traefik]
|
|
|
|
subgraph "Gateway Features"
|
|
Gateway --> Route[Routing]
|
|
Gateway --> LB[Load Balancing]
|
|
Gateway --> Auth[Authentication]
|
|
Gateway --> Rate[Rate Limiting]
|
|
Gateway --> CORS
|
|
end
|
|
|
|
Route --> Service1[Service 1]
|
|
Route --> Service2[Service 2]
|
|
LB --> Service1A[Instance A]
|
|
LB --> Service1B[Instance B]
|
|
|
|
%% Dark color palette with white text
|
|
classDef clientBlue fill:#1565c0,stroke:#fff,stroke-width:2px,color:#fff
|
|
classDef gatewayBlue fill:#0f4c81,stroke:#fff,stroke-width:2px,color:#fff
|
|
classDef featurePurple fill:#4527a0,stroke:#fff,stroke-width:2px,color:#fff
|
|
classDef serviceGreen fill:#1e3a29,stroke:#3c7a52,stroke-width:2px,color:#fff
|
|
|
|
class Client clientBlue
|
|
class Gateway gatewayBlue
|
|
class Route,LB,Auth,Rate,CORS featurePurple
|
|
class Service1,Service2,Service1A,Service1B serviceGreen
|
|
```
|
|
|
|
Điểm vào duy nhất cho tất cả client requests với routing, auth, rate limiting.
|
|
|
|
## Đặc điểm Hiệu suất
|
|
|
|
Kỳ vọng hiệu suất và chiến lược tối ưu cho giao tiếp giữa các services.
|
|
|
|
| Chỉ số | Mục tiêu | Ghi chú |
|
|
|------------------|-------------------|-----------------|
|
|
| **Thời gian phản hồi REST API** | < 100ms | P95 cho các cuộc gọi service-to-service nội bộ |
|
|
| **Độ trễ publish event** | < 50ms | Thời gian publish tới Kafka |
|
|
| **Service discovery lookup** | < 10ms | Thời gian phân giải DNS |
|
|
| **Chi phí routing của Gateway** | < 20ms | Độ trễ thêm vào bởi Traefik |
|
|
| **Thông lượng** | 10,000 req/s | Mỗi service instance |
|
|
| **Xử lý Kafka event** | < 500ms | P95 xử lý event end-to-end |
|
|
|
|
**Chiến lược Tối ưu**:
|
|
- **Connection Pooling**: Tái sử dụng HTTP connections giữa services
|
|
- **Circuit Breaker**: Ngăn chặn cascading failures với thư viện Opossum
|
|
- **Retry with Backoff**: Exponential backoff cho transient failures
|
|
- **Compression**: Bật gzip cho payloads lớn
|
|
- **Caching**: Cache kết quả service discovery và responses
|
|
|
|
## Cân nhắc Bảo mật
|
|
|
|
Biện pháp bảo mật để bảo vệ giao tiếp giữa các services.
|
|
|
|
### Xác thực Service-to-Service
|
|
|
|
- **Internal API Keys**: Services xác thực sử dụng `x-service-auth` header
|
|
- **JWT Tokens**: Để truyền user context giữa services
|
|
- **Mutual TLS (mTLS)**: Tùy chọn cho môi trường production (Kubernetes service mesh)
|
|
|
|
### Bảo mật Mạng
|
|
|
|
- **Network Policies**: Kubernetes NetworkPolicies hạn chế traffic service-to-service
|
|
- **Service Mesh**: Istio/Linkerd cho security policies nâng cao (tùy chọn)
|
|
- **Private Networks**: Services giao tiếp trong private VPC/cluster network
|
|
|
|
### Bảo vệ Dữ liệu
|
|
|
|
- **Encryption in Transit**: TLS 1.2+ cho mọi external communication
|
|
- **Event Payload Encryption**: Dữ liệu nhạy cảm được mã hóa trước khi publish tới Kafka
|
|
- **API Gateway**: Xử lý SSL termination và request validation
|
|
|
|
### Best Practices Bảo mật
|
|
|
|
```typescript
|
|
// Service client với xác thực
|
|
export class SecureServiceClient {
|
|
private client = axios.create({
|
|
baseURL: process.env.SERVICE_URL,
|
|
timeout: 5000,
|
|
headers: {
|
|
'x-service-auth': process.env.INTERNAL_API_KEY,
|
|
'x-correlation-id': generateCorrelationId()
|
|
},
|
|
httpsAgent: new https.Agent({
|
|
rejectUnauthorized: true // Xác minh SSL certificates
|
|
})
|
|
});
|
|
}
|
|
```
|
|
|
|
## Triển khai
|
|
|
|
Cách giao tiếp microservices được triển khai và mở rộng qua các môi trường.
|
|
|
|
```mermaid
|
|
graph TD
|
|
subgraph "Production Cluster"
|
|
LB[Load Balancer] --> Gateway[API Gateway<br/>3 replicas]
|
|
|
|
Gateway --> ServiceA1[Service A<br/>Instance 1]
|
|
Gateway --> ServiceA2[Service A<br/>Instance 2]
|
|
Gateway --> ServiceB1[Service B<br/>Instance 1]
|
|
Gateway --> ServiceB2[Service B<br/>Instance 2]
|
|
|
|
ServiceA1 & ServiceA2 --> Kafka[Kafka Cluster<br/>3 brokers]
|
|
ServiceB1 & ServiceB2 --> Kafka
|
|
|
|
ServiceA1 & ServiceA2 --> DB[(PostgreSQL<br/>Primary + Replica)]
|
|
ServiceB1 & ServiceB2 --> DB
|
|
|
|
ServiceA1 & ServiceA2 --> Redis[(Redis Cluster<br/>3 nodes)]
|
|
ServiceB1 & ServiceB2 --> Redis
|
|
end
|
|
|
|
%% Dark color palette with white text and white strokes
|
|
classDef lbGrey fill:#424242,stroke:#fff,stroke-width:2px,color:#fff
|
|
classDef gatewayBlue fill:#0f4c81,stroke:#fff,stroke-width:2px,color:#fff
|
|
classDef servicePurple fill:#4527a0,stroke:#fff,stroke-width:2px,color:#fff
|
|
classDef kafkaOrange fill:#3a2e1e,stroke:#fff,stroke-width:2px,color:#fff
|
|
classDef dbGreen fill:#1e3a29,stroke:#fff,stroke-width:2px,color:#fff
|
|
classDef redisRed fill:#3a1e1e,stroke:#fff,stroke-width:2px,color:#fff
|
|
|
|
class LB lbGrey
|
|
class Gateway gatewayBlue
|
|
class ServiceA1,ServiceA2,ServiceB1,ServiceB2 servicePurple
|
|
class Kafka kafkaOrange
|
|
class DB dbGreen
|
|
class Redis redisRed
|
|
```
|
|
|
|
### Môi trường Triển khai
|
|
|
|
| Environment | Gateway | Services | Kafka | Service Discovery |
|
|
|-------------|---------|----------|-------|-------------------|
|
|
| **Local** | Traefik (Docker) | Single instance per service | Single broker | Docker DNS |
|
|
| **Staging** | Traefik (2 replicas) | 2 replicas per service | 3 brokers | Kubernetes DNS |
|
|
| **Production** | Traefik (3+ replicas) | 3+ replicas per service | 5+ brokers | Kubernetes DNS + Service Mesh |
|
|
|
|
### Chiến lược Mở rộng
|
|
|
|
- **Horizontal Pod Autoscaler (HPA)**: Tự động scale dựa trên CPU/memory
|
|
- **Kafka Partitions**: Scale event processing bằng cách tăng partitions
|
|
- **Load Balancing**: Cân bằng tải giữa pod replicas
|
|
- **Gateway Scaling**: Traefik scale độc lập với backend services
|
|
|
|
## Giám sát & Khả năng quan sát
|
|
|
|
Cách giám sát và quan sát giao tiếp microservices.
|
|
|
|
### Chỉ số Chính
|
|
|
|
**Service-to-Service Metrics**:
|
|
- `http_request_duration_seconds` - Request latency histogram
|
|
- `http_requests_total` - Total requests counter
|
|
- `http_request_errors_total` - Failed requests counter
|
|
- `service_client_timeout_total` - Timeout counter
|
|
|
|
**Gateway Metrics**:
|
|
- `traefik_service_requests_total` - Requests per service
|
|
- `traefik_service_request_duration_seconds` - Routing latency
|
|
- `traefik_service_retries_total` - Retry attempts
|
|
|
|
**Kafka Metrics**:
|
|
- `kafka_producer_record_send_total` - Events published
|
|
- `kafka_consumer_lag` - Consumer lag
|
|
- `kafka_consumer_records_consumed_total` - Events consumed
|
|
|
|
### Kiểm tra Sức khỏe
|
|
|
|
**Service Endpoints**:
|
|
```typescript
|
|
// Liveness - service có đang chạy không?
|
|
app.get('/health/live', (req, res) => {
|
|
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
});
|
|
|
|
// Readiness - service có thể xử lý traffic không?
|
|
app.get('/health/ready', async (req, res) => {
|
|
const checks = {
|
|
database: await checkDatabase(),
|
|
redis: await checkRedis(),
|
|
kafka: await checkKafka()
|
|
};
|
|
|
|
const healthy = Object.values(checks).every(c => c);
|
|
res.status(healthy ? 200 : 503).json({ ready: healthy, checks });
|
|
});
|
|
```
|
|
|
|
**Kubernetes Probes**:
|
|
```yaml
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health/live
|
|
port: 3000
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 10
|
|
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health/ready
|
|
port: 3000
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 5
|
|
```
|
|
|
|
### Tracing Phân tán
|
|
|
|
- **OpenTelemetry**: Instrument tất cả service-to-service calls
|
|
- **Jaeger**: Hiển thị distributed traces
|
|
- **Correlation IDs**: Truyền qua `x-correlation-id` header để tracking requests
|
|
|
|
### Dashboard Giám sát
|
|
|
|
**Grafana Panels**:
|
|
- Service Communication Overview (request rate, latency, errors)
|
|
- Gateway Performance (routing time, backend health)
|
|
- Event Bus Health (Kafka lag, throughput)
|
|
- Service Dependencies (service map from traces)
|
|
|
|
## Tài liệu Liên quan
|
|
|
|
- [System Design](./system-design.md) - Kiến trúc tổng thể
|
|
- [Event-Driven Architecture](./event-driven-architecture.md) - Event patterns
|
|
- [API Gateway Advanced](../skills/api-gateway-advanced.md) - Gateway patterns
|
|
- [Inter-Service Communication](../skills/inter-service-communication.md) - Communication patterns
|
|
- [Resilience Patterns](../skills/resilience-patterns.md) - Circuit breaker, retry
|
|
|
|
---
|
|
|
|
## Quick Tips
|
|
|
|
### Mermaid Common Issues
|
|
- **Arrow Syntax**: `-->` (solid), `-.->` (dotted), `==>` (thick)
|
|
- **Special Characters**: Escape with quote marks `"`
|
|
- **Subgraphs**: Use `subgraph "Title"` ... `end`
|
|
|
|
### Color Pattern Quick Reference
|
|
| Element | Color | Hex | Stroke | Usage |
|
|
|---------|-------|-----|--------|-------|
|
|
| **Core** | Blue | `#253041` | `#4b6584` | Primary components |
|
|
| **Logic** | Purple | `#2e1e3a` | `#5f3c7a` | Processing steps |
|
|
| **Data** | Green | `#1e3a29` | `#3c7a52` | Database, Cache |
|
|
| **External** | Orange | `#3a2e1e` | `#7a5f3c` | External APIs |
|
|
| **Error** | Red | `#3a1e1e` | `#7a3c3c` | Failures, Alerts |
|
|
|
|
### Visual Indicators
|
|
- 🔵 **Blue**: Core Infrastructure
|
|
- 🟢 **Green**: Data Operations
|
|
- 🟠 **Orange**: Event/External
|
|
- 🔴 **Red**: Critical/Error
|
|
- ⚪ **Grey**: Neutral/Boundary
|
|
|
|
---
|
|
|
|
**Cập nhật lần cuối / Last Updated**: 2026-01-14
|
|
**Tác giả / Authors**: GoodGo Architecture Team
|
|
**Reviewers**: To be assigned
|