【go语言版httpclient系列】go语言http并发请求

业务背景

从文件中读取json串,同时向http server端发送请求。

直接贴代码

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)

// 准备要发送的 JSON 数据
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.")
}