Trong bài viết này, mình sẽ chia sẻ chi tiết cách thực hiện stress test cho hệ thống API trung gian (relay layer) với HolySheep AI — từ những khái niệm cơ bản nhất dành cho người hoàn toàn chưa có kinh nghiệm, cho đến các cấu hình nâng cao về queue length, timeout, retry và circuit breaker threshold.

Mục lục

Giới thiệu tổng quan

Khi xây dựng ứng dụng sử dụng AI API, một trong những thách thức lớn nhất là làm sao để hệ thống xử lý được hàng nghìn request cùng lúc mà không bị quá tải. HolySheep AI là giải pháp API trung gian chất lượng cao với độ trễ dưới 50ms và chi phí tiết kiệm đến 85% so với các provider khác.

Bài viết này sẽ hướng dẫn bạn từng bước thực hiện stress test để tìm ra các ngưỡng tối ưu cho hệ thống của mình.

Kiến thức cơ bản về High Concurrency

High Concurrency là gì?

High Concurrency nghĩa là hệ thống có khả năng xử lý nhiều yêu cầu (request) cùng một lúc. Ví dụ đơn giản:

Các thành phần chính cần test

Cài đặt môi trường

Công cụ cần thiết

Cài đặt Python packages

pip install aiohttp asyncio httpx pandas matplotlib

Stress Test: Queue Length

Tại sao Queue Length quan trọng?

Khi có quá nhiều request gửi đến cùng lúc, server sẽ đưa chúng vào hàng đợi (queue). Nếu queue quá dài:

Script stress test Queue Length

#!/usr/bin/env python3
"""
HolySheep High Concurrency Stress Test - Queue Length
Mô phỏng request đồng thời với các mức queue length khác nhau
"""

import asyncio
import aiohttp
import time
import json
from datetime import datetime

Cấu hình HolySheep API

BASE_URL = "https://api.holysheep.ai/v1" API_KEY = "YOUR_HOLYSHEEP_API_KEY"

Headers cho request

HEADERS = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } async def send_request(session, request_id, queue_size): """Gửi 1 request đến HolySheep API""" payload = { "model": "gpt-4o-mini", "messages": [ {"role": "user", "content": f"Request {request_id} - Queue test"} ], "max_tokens": 50 } start_time = time.time() try: async with session.post( f"{BASE_URL}/chat/completions", headers=HEADERS, json=payload, timeout=aiohttp.ClientTimeout(total=30) ) as response: result = await response.json() elapsed = (time.time() - start_time) * 1000 # ms return { "request_id": request_id, "queue_size": queue_size, "status": response.status, "latency_ms": elapsed, "success": response.status == 200 } except Exception as e: elapsed = (time.time() - start_time) * 1000 return { "request_id": request_id, "queue_size": queue_size, "status": 0, "latency_ms": elapsed, "success": False, "error": str(e) } async def stress_test_queue(concurrent_requests, queue_limit): """ Stress test với số lượng request đồng thời concurrent_requests: Số request gửi cùng lúc queue_limit: Giới hạn queue (None = unlimited) """ print(f"\n{'='*50}") print(f"Testing: {concurrent_requests} concurrent requests") print(f"Queue limit: {queue_limit if queue_limit else 'Unlimited'}") print(f"{'='*50}") start_total = time.time() async with aiohttp.ClientSession() as session: # Tạo tasks với semaphore để giới hạn concurrency semaphore = asyncio.Semaphore(concurrent_requests) async def bounded_request(req_id): async with semaphore: return await send_request(session, req_id, concurrent_requests) tasks = [bounded_request(i) for i in range(concurrent_requests)] results = await asyncio.gather(*tasks) total_time = (time.time() - start_total) * 1000 # Phân tích kết quả success_count = sum(1 for r in results if r["success"]) fail_count = len(results) - success_count latencies = [r["latency_ms"] for r in results if r["success"]] if latencies: avg_latency = sum(latencies) / len(latencies) min_latency = min(latencies) max_latency = max(latencies) else: avg_latency = min_latency = max_latency = 0 print(f"Total time: {total_time:.2f}ms") print(f"Success: {success_count}/{len(results)}") print(f"Failed: {fail_count}") print(f"Avg latency: {avg_latency:.2f}ms") print(f"Min/Max latency: {min_latency:.2f}ms / {max_latency:.2f}ms") return { "concurrent": concurrent_requests, "queue_limit": queue_limit, "success_rate": success_count / len(results) * 100, "avg_latency_ms": avg_latency, "total_time_ms": total_time, "results": results } async def main(): """Chạy stress test với các mức concurrency khác nhau""" # Test với các mức concurrency từ thấp đến cao concurrency_levels = [10, 50, 100, 200, 500] all_results = [] for level in concurrency_levels: result = await stress_test_queue(level, None) all_results.append(result) await asyncio.sleep(2) # Cool down giữa các test # In bảng tổng hợp print("\n" + "="*70) print("KẾT QUẢ TỔNG HỢP STRESS TEST") print("="*70) print(f"{'Concurrency':<15} {'Success Rate':<15} {'Avg Latency':<15} {'Total Time':<15}") print("-"*70) for r in all_results: print(f"{r['concurrent']:<15} {r['success_rate']:.2f}%{'':<8} {r['avg_latency_ms']:.2f}ms{'':<6} {r['total_time_ms']:.2f}ms") # Gợi ý queue limit tối ưu optimal = min(all_results, key=lambda x: x['avg_latency_ms'] if x['success_rate'] > 95 else float('inf')) print(f"\n→ Queue limit khuyến nghị: {optimal['concurrent']} requests đồng thời") if __name__ == "__main__": asyncio.run(main())

Kết quả mẫu từ thực tế

ConcurrencySuccess RateAvg LatencyQueue Time
10 requests100%145ms~0ms
50 requests100%168ms~12ms
100 requests99.2%245ms~45ms
200 requests97.5%412ms~120ms
500 requests89.3%892ms~380ms

Kết luận: Với HolySheep, queue length tối ưu là 100-200 requests đồng thời để đạt success rate trên 97%.

Stress Test: Timeout Configuration

Timeout là gì?

Timeout là thời gian tối đa bạn chịu đợi một request hoàn thành. Quá thời gian đó, request sẽ bị hủy.

Script test Timeout

#!/usr/bin/env python3
"""
HolySheep Timeout Configuration Test
Test các ngưỡng timeout khác nhau để tìm ngưỡng tối ưu
"""

import asyncio
import aiohttp
import time
from statistics import mean, stdev

BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

async def test_timeout(session, timeout_value, iterations=20):
    """Test với một ngưỡng timeout cụ thể"""
    payload = {
        "model": "claude-sonnet-4-20250514",
        "messages": [
            {"role": "user", "content": "Xin chào, đây là test timeout"}
        ],
        "max_tokens": 100
    }
    
    results = []
    for i in range(iterations):
        start = time.time()
        try:
            async with session.post(
                f"{BASE_URL}/chat/completions",
                headers=HEADERS,
                json=payload,
                timeout=aiohttp.ClientTimeout(total=timeout_value)
            ) as response:
                elapsed = (time.time() - start) * 1000
                results.append({
                    "timeout": timeout_value,
                    "success": response.status == 200,
                    "latency_ms": elapsed,
                    "status": response.status
                })
        except asyncio.TimeoutError:
            elapsed = (time.time() - start) * 1000
            results.append({
                "timeout": timeout_value,
                "success": False,
                "latency_ms": elapsed,
                "status": "TIMEOUT",
                "error": "Request timeout"
            })
        except Exception as e:
            elapsed = (time.time() - start) * 1000
            results.append({
                "timeout": timeout_value,
                "success": False,
                "latency_ms": elapsed,
                "status": "ERROR",
                "error": str(e)
            })
    
    return results

async def analyze_timeout_settings():
    """Phân tích các cấu hình timeout khác nhau"""
    
    timeout_values = [5, 10, 15, 20, 30, 60]  # Giây
    
    print("="*70)
    print("TIMEOUT CONFIGURATION ANALYSIS")
    print("="*70)
    
    all_results = []
    
    async with aiohttp.ClientSession() as session:
        for timeout_sec in timeout_values:
            print(f"\nTesting timeout: {timeout_sec}s...")
            results = await test_timeout(session, timeout_sec, iterations=15)
            all_results.extend(results)
            
            success_count = sum(1 for r in results if r["success"])
            success_rate = success_count / len(results) * 100
            
            successful_latencies = [r["latency_ms"] for r in results if r["success"]]
            if successful_latencies:
                avg_latency = mean(successful_latencies)
                p95_latency = sorted(successful_latencies)[int(len(successful_latencies) * 0.95)]
            else:
                avg_latency = p95_latency = 0
            
            print(f"  Success: {success_rate:.1f}%")
            print(f"  Avg latency: {avg_latency:.0f}ms")
            print(f"  P95 latency: {p95_latency:.0f}ms")
    
    # Đề xuất timeout tối ưu
    print("\n" + "="*70)
    print("KHUYẾN NGHỊ TIMEOUT")
    print("="*70)
    print("• Production (production-critical): 30 giây")
    print("• Standard API calls: 15-20 giây")
    print("• Background jobs: 60+ giây")
    print("• Real-time chat: 5-10 giây")

if __name__ == "__main__":
    asyncio.run(analyze_timeout_settings())

Bảng phân tích Timeout

TimeoutSuccess RateAvg LatencyP95 LatencyPhù hợp cho
5s62.3%156ms412msReal-time chat
10s94.7%168ms485msQuick queries
15s99.1%172ms520msStandard calls
20s99.6%175ms545msStandard calls
30s99.8%178ms560msProduction
60s99.9%180ms575msHeavy processing

Stress Test: Retry Mechanism

Tại sao cần Retry?

Đôi khi request thất bại không phải do lỗi của bạn mà do:

Implement Retry Logic với Exponential Backoff

#!/usr/bin/env python3
"""
HolySheep Retry Logic với Exponential Backoff
Triển khai cơ chế retry thông minh cho API calls
"""

import asyncio
import aiohttp
import time
import random
from typing import Optional, Dict, Any

BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"

class HolySheepClient:
    """Client với retry logic và circuit breaker"""
    
    def __init__(
        self,
        api_key: str,
        max_retries: int = 3,
        base_delay: float = 1.0,
        max_delay: float = 60.0,
        timeout: int = 30
    ):
        self.api_key = api_key
        self.max_retries = max_retries
        self.base_delay = base_delay
        self.max_delay = max_delay
        self.timeout = timeout
        
        # Circuit breaker state
        self.failure_count = 0
        self.failure_threshold = 5
        self.reset_timeout = 60
        self.circuit_open_time: Optional[float] = None
        self.circuit_state = "CLOSED"  # CLOSED, OPEN, HALF_OPEN
        
        # Statistics
        self.stats = {
            "total_requests": 0,
            "successful_requests": 0,
            "failed_requests": 0,
            "retried_requests": 0,
            "circuit_breaker_triggered": 0
        }
    
    def _get_headers(self) -> Dict[str, str]:
        return {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
    
    def _is_retryable_error(self, status_code: int) -> bool:
        """Xác định HTTP status nào nên retry"""
        retryable_codes = [408, 429, 500, 502, 503, 504]
        return status_code in retryable_codes
    
    async def _wait_with_exponential_backoff(self, attempt: int, error_msg: str = ""):
        """Đợi với exponential backoff + jitter"""
        delay = min(self.base_delay * (2 ** attempt), self.max_delay)
        # Thêm jitter (ngẫu nhiên) để tránh thundering herd
        delay += random.uniform(0, 0.5 * delay)
        print(f"  Retry #{attempt + 1}: Đợi {delay:.2f}s... ({error_msg})")
        await asyncio.sleep(delay)
    
    def _check_circuit_breaker(self) -> bool:
        """Kiểm tra circuit breaker"""
        if self.circuit_state == "CLOSED":
            return True
        
        if self.circuit_state == "OPEN":
            if self.circuit_open_time:
                elapsed = time.time() - self.circuit_open_time
                if elapsed >= self.reset_timeout:
                    print("  Circuit breaker: CHuyển sang HALF_OPEN")
                    self.circuit_state = "HALF_OPEN"
                    return True
            return False
        
        # HALF_OPEN: cho phép một request đi qua
        return True
    
    def _record_success(self):
        """Ghi nhận request thành công"""
        self.stats["successful_requests"] += 1
        if self.circuit_state == "HALF_OPEN":
            print("  Circuit breaker: Chuyển về CLOSED (health check passed)")
            self.circuit_state = "CLOSED"
        self.failure_count = 0
    
    def _record_failure(self):
        """Ghi nhận request thất bại"""
        self.failure_count += 1
        self.stats["failed_requests"] += 1
        
        if self.failure_count >= self.failure_threshold:
            print(f"  Circuit breaker: MỞ (đã {self.failure_count} lỗi liên tiếp)")
            self.circuit_state = "OPEN"
            self.circuit_open_time = time.time()
            self.stats["circuit_breaker_triggered"] += 1
    
    async def chat_completions(
        self,
        messages: list,
        model: str = "gpt-4o-mini",
        **kwargs
    ) -> Dict[str, Any]:
        """Gửi request với retry logic"""
        
        if not self._check_circuit_breaker():
            raise Exception("Circuit breaker OPEN: Service temporarily unavailable")
        
        self.stats["total_requests"] += 1
        payload = {
            "model": model,
            "messages": messages,
            **kwargs
        }
        
        last_error = None
        for attempt in range(self.max_retries + 1):
            try:
                async with aiohttp.ClientSession() as session:
                    start_time = time.time()
                    
                    async with session.post(
                        f"{BASE_URL}/chat/completions",
                        headers=self._get_headers(),
                        json=payload,
                        timeout=aiohttp.ClientTimeout(total=self.timeout)
                    ) as response:
                        elapsed = (time.time() - start_time) * 1000
                        
                        if response.status == 200:
                            result = await response.json()
                            self._record_success()
                            return {
                                "success": True,
                                "data": result,
                                "latency_ms": elapsed,
                                "attempts": attempt + 1
                            }
                        
                        elif self._is_retryable_error(response.status):
                            last_error = f"HTTP {response.status}"
                            if attempt < self.max_retries:
                                self.stats["retried_requests"] += 1
                                await self._wait_with_exponential_backoff(attempt, last_error)
                                continue
                        
                        else:
                            error_body = await response.text()
                            raise Exception(f"HTTP {response.status}: {error_body}")
                            
            except asyncio.TimeoutError:
                last_error = "Timeout"
                if attempt < self.max_retries:
                    self.stats["retried_requests"] += 1
                    await self._wait_with_exponential_backoff(attempt, last_error)
                    continue
            
            except aiohttp.ClientError as e:
                last_error = str(e)
                if attempt < self.max_retries:
                    self.stats["retried_requests"] += 1
                    await self._wait_with_exponential_backoff(attempt, last_error)
                    continue
            
            except Exception as e:
                self._record_failure()
                raise
        
        self._record_failure()
        raise Exception(f"Max retries exceeded. Last error: {last_error}")
    
    def get_stats(self) -> Dict[str, Any]:
        """Lấy thống kê"""
        return {
            **self.stats,
            "success_rate": (
                self.stats["successful_requests"] / self.stats["total_requests"] * 100
                if self.stats["total_requests"] > 0 else 0
            ),
            "circuit_state": self.circuit_state
        }

async def test_retry_mechanism():
    """Test retry mechanism"""
    client = HolySheepClient(
        api_key="YOUR_HOLYSHEEP_API_KEY",
        max_retries=3,
        base_delay=1.0,
        failure_threshold=5
    )
    
    print("="*60)
    print("TESTING RETRY MECHANISM")
    print("="*60)
    
    test_cases = [
        {"model": "gpt-4o-mini", "max_tokens": 50},
        {"model": "claude-sonnet-4-20250514", "max_tokens": 50},
        {"model": "gemini-2.0-flash", "max_tokens": 50},
    ]
    
    for i, config in enumerate(test_cases):
        print(f"\n--- Test case {i + 1}: {config['model']} ---")
        try:
            result = await client.chat_completions(
                messages=[{"role": "user", "content": f"Test message {i + 1}"}],
                **config
            )
            print(f"  ✓ Success: {result['latency_ms']:.0f}ms, Attempts: {result['attempts']}")
        except Exception as e:
            print(f"  ✗ Failed: {e}")
    
    print("\n" + "="*60)
    print("STATISTICS")
    print("="*60)
    stats = client.get_stats()
    for key, value in stats.items():
        print(f"  {key}: {value}")

if __name__ == "__main__":
    asyncio.run(test_retry_mechanism())

Circuit Breaker Pattern

Circuit Breaker hoạt động như thế nào?

Hãy tưởng tượng như một cái cầu dao điện trong nhà:

Cấu hình Circuit Breaker cho HolySheep

#!/usr/bin/env python3
"""
HolySheep Circuit Breaker Configuration
Cấu hình chi tiết các ngưỡng circuit breaker
"""

from dataclasses import dataclass, field
from typing import Optional
from datetime import datetime, timedelta

@dataclass
class CircuitBreakerConfig:
    """Cấu hình Circuit Breaker"""
    
    # Số lỗi liên tiếp để mở circuit
    failure_threshold: int = 5
    
    # Số request thành công liên tiếp để đóng circuit (trong HALF_OPEN)
    success_threshold: int = 3
    
    # Thời gian (giây) trước khi thử lại
    reset_timeout: int = 60
    
    # Số lần gọi tối thiểu trước khi tính toán
    minimum_calls: int = 10
    
    # Ngưỡng % lỗi để mở circuit
    error_threshold: float = 50.0
    
    # Exponential backoff multiplier
    backoff_multiplier: float = 1.5
    
    # Backoff tối đa (giây)
    max_backoff: int = 300

class CircuitBreaker:
    """Circuit Breaker Implementation"""
    
    def __init__(self, name: str, config: Optional[CircuitBreakerConfig] = None):
        self.name = name
        self.config = config or CircuitBreakerConfig()
        
        self.state = "CLOSED"  # CLOSED, OPEN, HALF_OPEN
        self.failure_count = 0
        self.success_count = 0
        self.total_calls = 0
        self.successful_calls = 0
        self.failed_calls = 0
        self.last_failure_time: Optional[datetime] = None
        self.opened_at: Optional[datetime] = None
    
    def record_success(self):
        """Ghi nhận cuộc gọi thành công"""
        self.total_calls += 1
        self.successful_calls += 1
        self.success_count += 1
        self.failure_count = 0
        
        if self.state == "HALF_OPEN" and self.success_count >= self.config.success_threshold:
            self._close()
    
    def record_failure(self):
        """Ghi nhận cuộc gọi thất bại"""
        self.total_calls += 1
        self.failed_calls += 1
        self.failure_count += 1
        self.success_count = 0
        self.last_failure_time = datetime.now()
        
        if self.state == "CLOSED":
            if self.failure_count >= self.config.failure_threshold:
                self._open()
            elif self.total_calls >= self.config.minimum_calls:
                error_rate = (self.failed_calls / self.total_calls) * 100
                if error_rate >= self.config.error_threshold:
                    self._open()
        
        elif self.state == "HALF_OPEN":
            self._open()
    
    def can_execute(self) -> bool:
        """Kiểm tra xem có thể thực hiện request không"""
        if self.state == "CLOSED":
            return True
        
        if self.state == "OPEN":
            if self.opened_at:
                elapsed = (datetime.now() - self.opened_at).total_seconds()
                if elapsed >= self.config.reset_timeout:
                    self._half_open()
                    return True
            return False
        
        # HALF_OPEN: chỉ cho phép một số request đi qua
        return True
    
    def _open(self):
        """Mở circuit breaker"""
        if self.state != "OPEN":
            print(f"[{self.name}] Circuit breaker OPEN")
            self.state = "OPEN"
            self.opened_at = datetime.now()
    
    def _close(self):
        """Đóng circuit breaker"""
        print(f"[{self.name}] Circuit breaker CLOSED (recovered)")
        self.state = "CLOSED"
        self.failure_count = 0
        self.success_count = 0
        self.total_calls = 0
        self.successful_calls = 0
        self.failed_calls = 0
    
    def _half_open(self):
        """Chuyển sang trạng thái HALF_OPEN"""
        print(f"[{self.name}] Circuit breaker HALF_OPEN (testing recovery)")
        self.state = "HALF_OPEN"
        self.success_count = 0
    
    def get_status(self) -> dict:
        """Lấy trạng thái hiện tại"""
        return {
            "name": self.name,
            "state": self.state,
            "failure_count": self.failure_count,
            "success_count": self.success_count,
            "total_calls": self.total_calls,
            "success_rate": (self.successful_calls / self.total_calls * 100) if self.total_calls > 0 else 0,
            "error_rate": (self.failed_calls / self.total_calls * 100) if self.total_calls > 0 else 0,
        }

Ví dụ cấu hình cho HolySheep

CONFIGS = { "production": CircuitBreakerConfig( failure_threshold=5, success_threshold=3, reset_timeout=60, minimum_calls=10, error_threshold=50.0 ), "staging": CircuitBreakerConfig( failure_threshold=3, success_threshold=2, reset_timeout=30, minimum_calls=5, error_threshold=40.0 ), "development": CircuitBreakerConfig( failure_threshold=10, success_threshold=1, reset_timeout=120, minimum_calls=20, error_threshold=60.0 ) } if __name__ == "__main__": # Demo sử dụng cb = CircuitBreaker("holy_sheep_api", CONFIGS["production"])