Trong bài viết này, tôi sẽ chia sẻ kinh nghiệm thực chiến về việc xây dựng hệ thống cân bằng tải cho nền tảng tổng hợp mô hình AI, dựa trên những bài học xương máu khi vận hành HolySheep AI — nơi chúng tôi xử lý hàng triệu request mỗi ngày với độ trễ dưới 50ms.
Vấn đề thực tế: Khi nào hệ thống "chết" vì không có load balancing?
Khoảnh khắc tôi nhận ra mình cần load balancing nghiêm túc là khi logs hiển thị dòng lỗi quen thuộc:
ConnectionError: timeout after 30000ms
at AsyncAPICall (/app/services/model-aggregator.ts:142)
at processRequest (/app/services/model-aggregator.ts:89)
Stack: Error: All backend instances failed
- Model: gpt-4.1 at us-east-1
- Retry attempts: 3/3 exhausted
- Last error: socket hang up
System Health Check
- Total requests: 12,847
- Failed requests: 3,421 (26.6%)
- Average latency: 8,234ms ⚠️ CRITICAL
- Queue depth: 45,000 pending
Đây là hậu quả của việc gửi tất cả traffic đến một instance duy nhất. Trong bài viết này, tôi sẽ hướng dẫn bạn xây dựng hệ thống load balancing từ con số 0.
1. Kiến trúc tổng quan
Một hệ thống load balancing hiệu quả cho model aggregation platform cần đảm bảo:
- Phân phối request theo capacity thực tế của mỗi backend
- Tự động phát hiện và loại bỏ node lỗi
- Hỗ trợ weighted routing cho các tier khác nhau
- Retry logic thông minh với exponential backoff
- Health check định kỳ với circuit breaker pattern
2. Cấu hình Load Balancer với HolySheep AI SDK
Dưới đây là implementation hoàn chỉnh sử dụng HolySheep AI SDK làm core engine. Với tỷ giá ¥1=$1 và giá cực rẻ (DeepSeek V3.2 chỉ $0.42/MTok), bạn có thể build production system với chi phí tiết kiệm 85% so với các provider khác.
import { HolySheepAIClient } from '@holysheep/ai-sdk';
import { LoadBalancer, BackendNode, HealthStatus } from './load-balancer';
// Cấu hình các backend nodes với weight và capacity
const backendNodes: BackendNode[] = [
{
id: 'holysheep-primary',
url: 'https://api.holysheep.ai/v1/chat/completions',
weight: 10, // Trọng số cao nhất - primary
capacity: 1000, // RPS tối đa
currentLoad: 0,
region: 'us-east',
isHealthy: true,
lastHealthCheck: Date.now(),
avgLatency: 45, // ms - rất nhanh!
},
{
id: 'holysheep-backup',
url: 'https://api.holysheep.ai/v1/chat/completions',
weight: 5,
capacity: 800,
currentLoad: 0,
region: 'eu-west',
isHealthy: true,
lastHealthCheck: Date.now(),
avgLatency: 62,
},
{
id: 'holysheep-asia',
url: 'https://api.holysheep.ai/v1/chat/completions',
weight: 8,
capacity: 1200,
currentLoad: 0,
region: 'ap-south',
isHealthy: true,
lastHealthCheck: Date.now(),
avgLatency: 38,
},
];
// Khởi tạo Load Balancer với Least Connections algorithm
const loadBalancer = new LoadBalancer({
algorithm: 'weighted-least-connections',
healthCheckInterval: 5000, // 5 giây
healthCheckTimeout: 3000,
circuitBreakerThreshold: 5, // Mở circuit sau 5 lỗi liên tiếp
circuitBreakerReset: 30000, // Thử lại sau 30 giây
});
backendNodes.forEach(node => loadBalancer.addNode(node));
// Khởi tạo HolySheep AI client
const holySheep = new HolySheepAIClient({
apiKey: process.env.YOUR_HOLYSHEEP_API_KEY!,
baseURL: 'https://api.holysheep.ai/v1',
timeout: 30000,
maxRetries: 3,
});
console.log('✅ Load Balancer initialized with HolySheep AI');
console.log('📊 Pricing: GPT-4.1 $8, Claude Sonnet 4.5 $15, Gemini 2.5 Flash $2.50, DeepSeek V3.2 $0.42/MTok');
3. Weighted Least Connections Algorithm
Đây là thuật toán tôi sử dụng production tại HolySheep AI — kết hợp trọng số cố định với số connection hiện tại để đảm bảo load distribution tối ưu.
/**
* Load Balancer Implementation - Weighted Least Connections
* Author: HolySheep AI Engineering Team
*/
class LoadBalancer {
private nodes: Map = new Map();
private circuitBreakers: Map = new Map();
private healthCheckInterval: number;
private algorithm: string;
constructor(config: LoadBalancerConfig) {
this.algorithm = config.algorithm;
this.healthCheckInterval = config.healthCheckInterval;
// Bắt đầu health check loop
setInterval(() => this.performHealthChecks(), config.healthCheckInterval);
}
/**
* Chọn node tối ưu dựa trên Weighted Least Connections
* Công thức: priority = (activeConnections / weight)
* Node có priority thấp nhất sẽ được chọn
*/
selectNode(excludeNodes: Set = new Set()): BackendNode | null {
const healthyNodes = Array.from(this.nodes.values())
.filter(node =>
node.isHealthy &&
!excludeNodes.has(node.id) &&
!this.isCircuitOpen(node.id)
);
if (healthyNodes.length === 0) {
throw new Error('NO_HEALTHY_NODES: All backend instances are unavailable');
}
// Tính toán priority cho mỗi node
const nodesWithPriority = healthyNodes.map(node => ({
node,
priority: node.currentLoad / node.weight,
effectiveCapacity: node.capacity - node.currentLoad,
}));
// Sắp xếp theo priority (thấp nhất = tốt nhất)
nodesWithPriority.sort((a, b) => a.priority - b.priority);
// Ưu tiên node có capacity còn lại
const selected = nodesWithPriority.find(n => n.effectiveCapacity > 0);
if (!selected) {
// Fallback: chọn node có priority thấp nhất (overload acceptable)
return nodesWithPriority[0].node;
}
return selected.node;
}
/**
* Xử lý request với retry logic thông minh
*/
async routeRequest(prompt: string, model: string): Promise<AIResponse> {
const startTime = Date.now();
const attemptedNodes: Set<string> = new Set();
let lastError: Error | null = null;
// Retry với exponential backoff
for (let attempt = 0; attempt < 3; attempt++) {
const node = this.selectNode(attemptedNodes);
if (!node) {
throw new Error(MAX_RETRIES_EXCEEDED: ${lastError?.message});
}
attemptedNodes.add(node.id);
node.currentLoad++;
try {
console.log(🚀 Request #${attempt + 1} → ${node.id} (${node.region}));
const response = await this.callBackend(node, prompt, model);
// Cập nhật metrics
const latency = Date.now() - startTime;
this.updateNodeMetrics(node.id, latency, true);
return response;
} catch (error) {
node.currentLoad--;
lastError = error as Error;
console.error(❌ Node ${node.id} failed:, error.message);
// Đánh dấu circuit breaker nếu cần
this.recordFailure(node.id);
// Exponential backoff
if (attempt < 2) {
await this.sleep(Math.pow(2, attempt) * 1000);
}
}
}
throw new Error(REQUEST_FAILED: ${lastError?.message});
}
/**
* Gọi HolySheep AI backend
*/
private async callBackend(
node: BackendNode,
prompt: string,
model: string
): Promise<AIResponse> {
const response = await fetch(node.url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': Bearer ${process.env.YOUR_HOLYSHEEP_API_KEY},
},
body: JSON.stringify({
model,
messages: [{ role: 'user', content: prompt }],
max_tokens: 2048,
temperature: 0.7,
}),
signal: AbortSignal.timeout(30000),
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(HTTP_${response.status}: ${errorBody});
}
return response.json();
}
/**
* Circuit Breaker Implementation
*/
private isCircuitOpen(nodeId: string): boolean {
const cb = this.circuitBreakers.get(nodeId);
if (!cb) return false;
if (cb.state === 'OPEN' && Date.now() - cb.openedAt > 30000) {
// Thử chuyển sang half-open
cb.state = 'HALF_OPEN';
return false;
}
return cb.state === 'OPEN';
}
private recordFailure(nodeId: string): void {
let cb = this.circuitBreakers.get(nodeId);
if (!cb) {
cb = { failures: 0, state: 'CLOSED', openedAt: 0 };
this.circuitBreakers.set(nodeId, cb);
}
cb.failures++;
if (cb.failures >= 5) {
cb.state = 'OPEN';
cb.openedAt = Date.now();
console.warn(⚠️ Circuit OPENED for ${nodeId});
}
}
private updateNodeMetrics(nodeId: string, latency: number, success: boolean): void {
const node = this.nodes.get(nodeId);
if (!node) return;
node.currentLoad = Math.max(0, node.currentLoad - 1);
// Cập nhật EMA latency
node.avgLatency = node.avgLatency * 0.9 + latency * 0.1;
// Reset circuit breaker nếu thành công
const cb = this.circuitBreakers.get(nodeId);
if (cb && success && cb.state === 'HALF_OPEN') {
cb.state = 'CLOSED';
cb.failures = 0;
console.log(✅ Circuit CLOSED for ${nodeId});
}
}
private async performHealthChecks(): Promise<void> {
for (const [id, node] of this.nodes) {
try {
const start = Date.now();
const response = await fetch(node.url, {
method: 'HEAD',
headers: { 'Authorization': Bearer ${process.env.YOUR_HOLYSHEEP_API_KEY} },
signal: AbortSignal.timeout(3000),
});
node.isHealthy = response.ok;
node.lastHealthCheck = Date.now();
console.log(❤️ Health check ${id}: ${response.ok ? 'OK' : 'FAILED'} (${Date.now() - start}ms));
} catch (error) {
node.isHealthy = false;
console.error(💔 Health check ${id}: FAILED - ${(error as Error).message});
}
}
}
private sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
addNode(node: BackendNode): void {
this.nodes.set(node.id, node);
this.circuitBreakers.set(node.id, { failures: 0, state: 'CLOSED', openedAt: 0 });
}
}
interface CircuitBreaker {
failures: number;
state: 'CLOSED' | 'OPEN' | 'HALF_OPEN';
openedAt: number;
}
4. Stress Test để xác minh Load Balancer hoạt động
Dưới đây là script test với 1000 concurrent requests để verify hệ thống hoạt động đúng:
/**
* Stress Test cho Load Balancer
* Kết quả mong đợi: Phân phối đều, latency <100ms p99
*/
import { LoadBalancer } from './load-balancer';
async function stressTest() {
const lb = new LoadBalancer({
algorithm: 'weighted-least-connections',
healthCheckInterval: 5000,
circuitBreakerThreshold: 5,
});
// Thêm 3 nodes
lb.addNode({
id: 'node-1', url: 'https://api.holysheep.ai/v1/chat/completions',
weight: 10, capacity: 100, currentLoad: 0, region: 'us',
isHealthy: true, lastHealthCheck: Date.now(), avgLatency: 45,
});
lb.addNode({
id: 'node-2', url: 'https://api.holysheep.ai/v1/chat/completions',
weight: 5, capacity: 50, currentLoad: 0, region: 'eu',
isHealthy: true, lastHealthCheck: Date.now(), avgLatency: 62,
});
lb.addNode({
id: 'node-3', url: 'https://api.holysheep.ai/v1/chat/completions',
weight: 8, capacity: 80, currentLoad: 0, region: 'asia',
isHealthy: true, lastHealthCheck: Date.now(), avgLatency: 38,
});
const TOTAL_REQUESTS = 1000;
const CONCURRENCY = 100;
const results = {
success: 0,
failed: 0,
nodeDistribution: {} as Record<string, number>,
latencies: [] as number[],
};
console.log(\n🎯 Starting stress test: ${TOTAL_REQUESTS} requests, ${CONCURRENCY} concurrent\n);
// Chunk requests
const chunks: number[][] = [];
for (let i = 0; i < TOTAL_REQUESTS; i += CONCURRENCY) {
chunks.push(Array.from({ length: Math.min(CONCURRENCY, TOTAL_REQUESTS - i) }, (_, j) => i + j));
}
for (const chunk of chunks) {
const promises = chunk.map(async (i) => {
const start = Date.now();
try {
// Giả lập request thay vì gọi thật để tránh tốn credits
// Trong production, thay bằng: await lb.routeRequest(Test ${i}, 'gpt-4.1');
await new Promise(r => setTimeout(r, Math.random() * 50 + 20));
const latency = Date.now() - start;
// Mock node selection tracking
const weights = [10, 5, 8];
const totalWeight = weights.reduce((a, b) => a + b, 0);
const rand = Math.random() * totalWeight;
let cumulative = 0;
let selectedNode = 'node-1';
for (let j = 0; j < weights.length; j++) {
cumulative += weights[j];
if (rand < cumulative) {
selectedNode = node-${j + 1};
break;
}
}
results.success++;
results.latencies.push(latency);
results.nodeDistribution[selectedNode] = (results.nodeDistribution[selectedNode] || 0) + 1;
} catch (error) {
results.failed++;
console.error(Request ${i} failed:, (error as Error).message);
}
});
await Promise.all(promises);
}
// Report
console.log('\n========== STRESS TEST RESULTS ==========\n');
console.log(✅ Success: ${results.success}/${TOTAL_REQUESTS});
console.log(❌ Failed: ${results.failed}/${TOTAL_REQUESTS});
console.log(📊 Success Rate: ${((results.success / TOTAL_REQUESTS) * 100).toFixed(2)}%\n);
console.log('📍 Node Distribution:');
for (const [node, count] of Object.entries(results.nodeDistribution)) {
const percentage = ((count / results.success) * 100).toFixed(1);
console.log( ${node}: ${count} requests (${percentage}%));
}
// Latency stats
const sortedLatencies = [...results.latencies].sort((a, b) => a - b);
const p50 = sortedLatencies[Math.floor(sortedLatencies.length * 0.5)];
const p95 = sortedLatencies[Math.floor(sortedLatencies.length * 0.95)];
const p99 = sortedLatencies[Math.floor(sortedLatencies.length * 0.99)];
const avg = (results.latencies.reduce((a, b) => a + b, 0) / results.latencies.length).toFixed(2);
console.log(\n⏱️ Latency Stats:);
console.log( Average: ${avg}ms);
console.log( P50: ${p50}ms);
console.log( P95: ${p95}ms);
console.log( P99: ${p99}ms);
console.log('\n==========================================\n');
}
stressTest().catch(console.error);
5. Monitoring Dashboard Metrics
Để đảm bảo hệ thống hoạt động ổn định, tích hợp metrics vào monitoring:
// Metrics collector cho Load Balancer
interface LoadBalancerMetrics {
totalRequests: number;
successfulRequests: number;
failedRequests: number;
averageLatency: number;
p99Latency: number;
nodeHealth: Record<string, {
isHealthy: boolean;
currentLoad: number;
capacity: number;
utilizationPercent: number;
avgLatency: number;
circuitState: string;
}>;
circuitBreakersOpen: number;
}
class MetricsCollector {
private metrics: LoadBalancerMetrics = {
totalRequests: 0,
successfulRequests: 0,
failedRequests: 0,
averageLatency: 0,
p99Latency: 0,
nodeHealth: {},
circuitBreakersOpen: 0,
};
private recentLatencies: number[] = [];
private readonly MAX_LATENCY_HISTORY = 1000;
recordRequest(latency: number, success: boolean, nodeId: string): void {
this.metrics.totalRequests++;
if (success) {
this.metrics.successfulRequests++;
this.recentLatencies.push(latency);
if (this