package main import ( "bytes" "encoding/json" "fmt" "net/http" "sync" "time" ) // 请求体结构 type UserRequest struct { UserID int `json:"user_id"` } // 响应体结构(根据实际接口响应调整) type Response struct { Success bool `json:"success"` Message string `json:"message"` } func main() { 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) } 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) } } // 等待所有请求完成 wg.Wait() fmt.Println("所有请求已完成") } // 发送POST请求 func sendPostRequest(userID int) (*Response, error) { url := "http://localhost:9096/user/kill" // 创建请求体 requestBody := UserRequest{ UserID: userID, } // 转换为JSON jsonBody, err := json.Marshal(requestBody) if err != nil { return nil, fmt.Errorf("JSON序列化失败: %v", err) } // 发送POST请求 resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonBody)) if err != nil { return nil, fmt.Errorf("请求发送失败: %v", err) } defer resp.Body.Close() // 解析响应(无论状态码如何都尝试解析,以便获取详细信息) 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 }