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