业务背景
用于:模拟对业务系统的某个接口同时发起多次请求。以便于测试服务端接口的幂等性效果。
直接贴代码
package main
import ( "bytes" "fmt" "io/ioutil" "net/http" "os" "strconv" "sync" "time" )
func main() { url := os.Args[1] filePath := os.Args[2] // 定义要发起的请求数量 numRequests, _ := strconv.Atoi(os.Args[3])
// 创建等待组,用于等待所有请求完成 var wg sync.WaitGroup wg.Add(numRequests)
// 定义通道,用于协调goroutine之间的通信 ch := make(chan struct{}, numRequests)
jsonBytes, _ := ioutil.ReadFile(filePath)
// 发起并发请求 for i:=0; i<numRequests; i++ { go func(i int) { // 将goroutine添加到等待组,以便在结束时通知等待组 defer wg.Done()
// 构造HTTP请求 req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBytes)) if err != nil { fmt.Printf("Error creating request: %v\n", err) return } req.Header.Set("Content-Type", "application/json")
// 发送HTTP请求 start := time.Now() client := &http.Client{} resp, err := client.Do(req) if err != nil { fmt.Printf("Error sending request: %v\n", err) return } body, err := ioutil.ReadAll(resp.Body) fmt.Println("response", string(body)) defer resp.Body.Close()
// 打印请求耗时 fmt.Printf("Request %d took %v\n", i, time.Since(start))
// 向通道发送信号,表示该请求已完成 ch <- struct{}{} }(i) }
// 等待所有请求完成 wg.Wait()
// 关闭通道 close(ch)
// 等待所有goroutine接收通道信号并退出 for range ch { }
fmt.Println("All requests completed.") }
|