修改1000个用户模拟思路

This commit is contained in:
2025-09-13 22:57:09 +08:00
parent 34301ee6ca
commit 9dd5a22b6c

View File

@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"sync" "sync"
"time"
) )
// 请求体结构 // 请求体结构
@@ -21,30 +22,58 @@ type Response struct {
func main() { func main() {
const totalUsers = 1000 // 总用户数 const totalUsers = 1000 // 总用户数
const concurrencyLimit = 100 // 并发控制,避免过多同时连接 const batchSize = 130 // 每批发送的请求数
const interval = 5 * time.Second // 每批请求的时间间隔
const duration = 20 * time.Second // 总持续时间
// 创建信号量控制并发数量 // 计算总批次数确保在duration时间内发送完所有请求
semaphore := make(chan struct{}, concurrencyLimit) totalBatches := totalUsers / batchSize
var wg sync.WaitGroup if totalUsers%batchSize != 0 {
totalBatches++
for i := 1; i <= totalUsers; i++ {
wg.Add(1)
semaphore <- struct{}{} // 获取信号量
go func(userID int) {
defer wg.Done()
defer func() { <-semaphore }() // 释放信号量
// 发送POST请求
result, err := sendPostRequest(userID)
if err != nil {
fmt.Printf("用户 %d 请求失败: %v\n", userID, err)
return
} }
// 输出结果 // 检查总耗时是否符合预期
fmt.Printf("用户 %d 响应: %+v\n", userID, result) expectedDuration := time.Duration(totalBatches-1) * interval
}(i) if expectedDuration > duration {
fmt.Printf("警告:按当前设置将耗时 %v超过预期的 %v\n", expectedDuration, duration)
}
var wg sync.WaitGroup
userID := 1 // 用户ID计数器
// 按批次发送请求
for batch := 1; batch <= totalBatches; batch++ {
// 计算当前批次的请求数量最后一批可能不足batchSize
currentBatchSize := batchSize
if userID+currentBatchSize-1 > totalUsers {
currentBatchSize = totalUsers - userID + 1
}
fmt.Printf("开始第 %d 批请求,共 %d 个,当前时间: %v\n",
batch, currentBatchSize, time.Now().Format("15:04:05"))
// 发送当前批次的请求
for i := 0; i < currentBatchSize; i++ {
wg.Add(1)
go func(uid int) {
defer wg.Done()
// 发送POST请求
result, err := sendPostRequest(uid)
if err != nil {
fmt.Printf("用户 %d 请求失败: %v\n", uid, err)
return
}
// 输出结果(可以根据需要调整输出频率,避免日志过多)
fmt.Printf("用户 %d 响应: %+v\n", uid, result)
}(userID)
userID++
}
// 最后一批不需要等待
if batch < totalBatches {
// 等待指定间隔后再发送下一批
time.Sleep(interval)
}
} }
// 等待所有请求完成 // 等待所有请求完成
@@ -74,17 +103,24 @@ func sendPostRequest(userID int) (*Response, error) {
} }
defer resp.Body.Close() defer resp.Body.Close()
// 检查响应状态码 // 解析响应(无论状态码如何都尝试解析,以便获取详细信息)
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("响应状态码异常: %d", resp.StatusCode)
}
// 解析响应
var response Response var response Response
decoder := json.NewDecoder(resp.Body) decoder := json.NewDecoder(resp.Body)
if err := decoder.Decode(&response); err != nil { if err := decoder.Decode(&response); err != nil {
return nil, fmt.Errorf("响应解析失败: %v", err) return nil, fmt.Errorf("响应解析失败: %v", err)
} }
// 检查响应状态码
// 状态码异常时,返回包含完整响应的错误信息
if resp.StatusCode != http.StatusOK {
// 将完整响应转为JSON字符串便于查看
responseJSON, _ := json.MarshalIndent(response, "", " ")
return &response, fmt.Errorf(
"状态码异常: %d, 响应内容: %s",
resp.StatusCode,
responseJSON,
)
}
return &response, nil return &response, nil
} }