2025-09-13 20:00:34 +08:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"bytes"
|
|
|
|
|
|
"encoding/json"
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"net/http"
|
|
|
|
|
|
"sync"
|
2025-09-13 22:57:09 +08:00
|
|
|
|
"time"
|
2025-09-13 20:00:34 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 请求体结构
|
|
|
|
|
|
type UserRequest struct {
|
|
|
|
|
|
UserID int `json:"user_id"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 响应体结构(根据实际接口响应调整)
|
|
|
|
|
|
type Response struct {
|
|
|
|
|
|
Success bool `json:"success"`
|
|
|
|
|
|
Message string `json:"message"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func main() {
|
2025-09-13 22:57:09 +08:00
|
|
|
|
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++
|
|
|
|
|
|
}
|
2025-09-13 20:00:34 +08:00
|
|
|
|
|
2025-09-13 22:57:09 +08:00
|
|
|
|
// 检查总耗时是否符合预期
|
|
|
|
|
|
expectedDuration := time.Duration(totalBatches-1) * interval
|
|
|
|
|
|
if expectedDuration > duration {
|
|
|
|
|
|
fmt.Printf("警告:按当前设置将耗时 %v,超过预期的 %v\n", expectedDuration, duration)
|
|
|
|
|
|
}
|
2025-09-13 20:00:34 +08:00
|
|
|
|
|
2025-09-13 22:57:09 +08:00
|
|
|
|
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)
|
|
|
|
|
|
}
|
2025-09-13 20:00:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 等待所有请求完成
|
|
|
|
|
|
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()
|
|
|
|
|
|
|
2025-09-13 22:57:09 +08:00
|
|
|
|
// 解析响应(无论状态码如何都尝试解析,以便获取详细信息)
|
2025-09-13 20:00:34 +08:00
|
|
|
|
var response Response
|
|
|
|
|
|
decoder := json.NewDecoder(resp.Body)
|
|
|
|
|
|
if err := decoder.Decode(&response); err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("响应解析失败: %v", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-13 22:57:09 +08:00
|
|
|
|
// 检查响应状态码
|
|
|
|
|
|
// 状态码异常时,返回包含完整响应的错误信息
|
|
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
|
|
|
|
// 将完整响应转为JSON字符串,便于查看
|
|
|
|
|
|
responseJSON, _ := json.MarshalIndent(response, "", " ")
|
|
|
|
|
|
return &response, fmt.Errorf(
|
|
|
|
|
|
"状态码异常: %d, 响应内容: %s",
|
|
|
|
|
|
resp.StatusCode,
|
|
|
|
|
|
responseJSON,
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-13 20:00:34 +08:00
|
|
|
|
return &response, nil
|
|
|
|
|
|
}
|