231 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

### 技术选型
- **语言**Go。
- **HTTP客户端**
- 抽象接口:`HTTPClient`
- 实现:
- `fasthttp``github.com/valyala/fasthttp`):高性能,优先选择。
- `net/http`(标准库):兼容性强,备选。
- **Tokenizer 库**`github.com/tiktoken-go/tokenizer`
- **并发管理**goroutine池、`sync.Pool``context.Context`
- **数据处理**`sync.Map`存储响应数据,`gonum/stat`计算百分位数。
- **图表生成**`go-echarts`
### 产品需求设计
#### 功能需求
- **API兼容性**
- 支持OpenAI Compatible风格的LLM API包括`stream=true`的SSE流式响应
- 兼容推理模型如DeepSeek-R1的响应结构包含`reasoning_content`字段(与`content`同级)。
- **HTTP客户端抽象层**
- 定义`HTTPClient`接口,包含以下方法:
- `Do(req *Request) (*Response, error)`:发送非流式请求。
- `Stream(req *Request, callback func(chunk SSEChunk) error) error`处理流式响应逐块回调SSE数据。
- 实现:
- `fasthttp`:基于`fasthttp.RequestCtx``Response.BodyStream`
- `net/http`:基于`http.Client``Response.Body`
- 配置项`client: "fasthttp"``client: "net-http"`切换客户端。
- **提示词生成**
- 使用`tiktoken-go/tokenizer`动态生成短咨询提示词50 tokens ±5%和长文档提示词1000 tokens ±5%)。
- **并发请求**
- 支持最大500并发持续5分钟300秒或更长时间。
- 使用goroutine池最大600 goroutine`sync.Pool`重用请求对象。
- 通过`context.Context`支持任务终止。
- **场景建模**
- 混合负载短咨询50 tokens70%比例长文档生成1000 tokens30%比例)。
- **用户行为模拟**:请求间隔遵循泊松分布(`math/rand`实现)。
- **梯度增压**支持阶梯式加压50→200→500并发每阶段持续300秒。
- **性能指标收集**
- **请求统计**:总请求数、成功请求数、失败请求数、超时比率(目标:<1%默认超时30-60秒)。
- **响应时间**平均最小/最大P90/P95/P99目标<2秒至<10秒<3秒至<15秒<5秒至<20秒)。
- **TTFT**
- 最小/最大TTFTP90/P95/P99 TTFT
- 通过SSE流式响应测量精度达毫秒兼容`content``reasoning_content`
- **QPS**平均QPS目标50-200+最大QPS
- **Token生成速率**平均速率目标>100 tokens/秒),最大速率,兼容`content``reasoning_content`
- **最大有效并发用户数**记录仍有请求成功的最大并发数目标50-500+)。
- **报告生成**
- 生成质量报告,包含所有指标统计。
- 提供图表如响应时间分布、TTFT分布、QPS曲线
#### 非功能需求
- **高性能**
- 支持500并发持续5分钟以上`fasthttp`优化吞吐量goroutine池降低GC压力。
- **统计准确性**
- TTFT和响应时间测量精度达毫秒使用`time.Now().UnixNano()`
- 使用`sync.Mutex``sync/atomic`确保并发统计线程安全。
- **可扩展性**:支持新服务提供商、提示词模板、响应字段。
- **易用性**配置文件指定API、提示词、超时、客户端类型`fasthttp``net-http`)。
- **稳定性**:长时间运行无崩溃、死锁或内存泄漏。
- **可观测性**
- 使用`log`包记录关键事件和错误,通过`--debug`参数,开启调试日志,记录详细信息。
- 使用`runtime`包监控CPU、内存、goroutine数。
- 使用`sync.Map`存储响应数据,`gonum/stat`计算百分位数。
#### 技术实现建议
- **HTTP客户端抽象层**
- 定义`HTTPClient`接口:
```go
type HTTPClient interface {
Do(req *Request) (*Response, error)
Stream(req *Request, callback func(chunk SSEChunk) error) error
}
type Request struct {
Method string
URL string
Body []byte
Headers map[string]string
}
type Response struct {
StatusCode int
Body []byte
Headers map[string]string
}
type SSEChunk struct {
Data []byte // JSON数据
Timestamp int64 // 接收时间戳UnixNano
IsDone bool // 是否为[data: [DONE]]
}
```
- **fasthttp实现**
- `Do`:使用`fasthttp.Do`构造OpenAI Compatible JSON请求解析响应。
- `Stream`:使用`fasthttp.Response.BodyStream`逐行解析SSE`data: {...}`),调用回调函数传递`SSEChunk`。
- 使用`sync.Pool`重用`fasthttp.Request`和`fasthttp.Response`。
- **net/http实现**
- `Do`:使用`http.Client.Do`,构造请求,解析响应。
- `Stream`:使用`bufio.Scanner`读取`http.Response.Body`解析SSE调用回调函数。
- **切换逻辑**
- 解析配置项`client`,实例化对应客户端:
```go
func NewHTTPClient(clientType string) (HTTPClient, error) {
switch clientType {
case "fasthttp":
return &FastHTTPClient{}, nil
case "net-http":
return &NetHTTPClient{}, nil
default:
return nil, fmt.Errorf("unsupported client: %s", clientType)
}
}
```
- **SSE与TTFT处理**
- `Stream`方法逐块解析SSE提取`choices[0].delta.content`或`choices[0].delta.reasoning_content`。
- 记录请求发送时间(`t0 = time.Now().UnixNano()`)。
- 检测首个非空Token块记录时间`t1`TTFT = (`t1 - t0`) / 1e6毫秒
- 兼容推理模型:优先检查`reasoning_content`,若为空则使用`content`。
- **Go性能优化**
- **Goroutine池**:使用`ants`库或自定义池限制最大600 goroutine。
- **对象池**`sync.Pool`重用请求/响应对象。
- **上下文控制**`context.WithTimeout`设置压测时长默认300秒
- **资源监控**:使用`runtime`包记录CPU、内存、goroutine数。
- **统计准确性**
- 使用`sync/atomic`累加请求计数。
- 使用`sync.Mutex`保护响应时间和TTFT切片。
- 使用`gonum/stat`计算P90/P95/P99。
- **提示词生成**`tiktoken-go/tokenizer`动态调整模板至50或1000 tokens。
- **报告生成**`go-echarts`生成图表模板引擎生成HTML/PDF。
#### 压测流程
1. **配置加载**读取API端点、客户端类型`fasthttp`或`net-http`)、并发数、提示词模板等。
2. **初始化HTTP客户端**:根据配置项`client`实例化`fasthttp`或`net/http`客户端。
3. **提示词生成**:使用`tiktoken-go/tokenizer`生成短咨询50 tokens和长文档1000 tokens提示词。
4. **并发执行**
- 初始化goroutine池最大600
- 使用`HTTPClient.Stream`发送请求(`stream=true`),间隔符合泊松分布。
- 处理SSE流记录TTFT。
5. **响应处理**
- 解析`content`和`reasoning_content`计算Token数。
- 记录响应时间、TTFT、成功/失败状态。
6. **指标计算**
- 计算请求统计、响应时间、TTFT、QPS、Token生成速率、最大并发用户数。
7. **报告生成**:输出统计数据和图表。
#### 配置示例与报告内容
以下是更新后的配置和报告示例包含HTTP客户端抽象层和切换逻辑
```yaml
# 配置示例
api:
endpoint: "https://api.example.com/v1/completions"
api_key: "your_api_key"
model: "deepseek-r1" # 支持推理模型
streaming: true # 启用流式响应
client: "fasthttp" # HTTP客户端fasthttp 或 net-http
prompt_templates:
short:
target_tokens: 50
templates:
- "What is the capital of {country}?"
- "Please briefly explain the concept of {concept}."
- "Summarize the main idea of {topic} in one sentence."
long:
target_tokens: 1000
templates:
- "Write a detailed history of {country} covering major events."
- "Compose an in-depth analysis of {topic} with examples."
- "Generate a comprehensive report on the impact of {event}."
requests:
- type: "short"
weight: 0.7
- type: "long"
weight: 0.3
concurrency:
steps: [50, 200, 500]
duration_per_step: 300 # 秒5分钟
max_goroutines: 600 # 最大goroutine数
timeout: 60 # 秒
poisson_lambda: 1.0 # 请求间隔泊松分布参数
tokenizer:
model: "gpt-3.5-turbo" # 用于tiktoken-go的分词器模型
# 报告内容示例
report:
overview:
api_endpoint: "https://api.example.com/v1/completions"
model: "deepseek-r1"
concurrency_steps: [50, 200, 500]
duration_per_step: "300s"
request_mix: "70% short (50 tokens), 30% long (1000 tokens)"
tokenizer: "tiktoken-go (gpt-3.5-turbo)"
streaming_enabled: true
http_client: "fasthttp"
metrics:
total_requests: 15000
successful_requests: 14850
failed_requests: 150
timeout_ratio: "1.0%"
response_time:
avg: "1.8s"
min: "0.5s"
max: "10.2s"
p90: "2.5s"
p95: "3.0s"
p99: "4.5s"
ttft:
min: "0.1s"
max: "2.0s"
p90: "0.3s"
p95: "0.4s"
p99: "0.6s"
qps:
avg: 180
max: 220
token_rate:
avg: "120 tokens/s"
max: "150 tokens/s"
max_concurrent_users: 500
resource_usage:
avg_cpu: "60%"
max_memory: "1.1GB"
max_goroutines: 600
charts:
- "response_time_distribution.png"
- "ttft_distribution.png"
- "qps_over_time.png"
- "token_rate_over_time.png"
- "concurrency_vs_response_time.png"
```