在 Go 中,最大化并发 HTTP 请求涉及解决文件描述符限制。超过这些限制导致的常见错误是:
net/http: Request.Body is closed
改进的并发方法
这是使用工作池和信号量通道的更有效的并发实现:
import ( "fmt" "log" "net/http" "runtime" "sync" "time" ) // Default values var ( reqs = 1000000 maxWorkers = 200 sem = make(chan bool, maxWorkers) respChan = make(chan *http.Response) respErrChan = make(chan error) ) func main() { runtime.GOMAXPROCS(runtime.NumCPU()) // Dispatcher: sends requests to the worker pool go func() { for i := 0; i < reqs; i++ { sem <- true req, err := http.NewRequest(http.MethodGet, "http://localhost:8080", nil) if err != nil { respErrChan <- err return } client := &http.Client{Timeout: 15 * time.Second} resp, err := client.Do(req) if err != nil { respErrChan <- err return } respChan <- resp } close(sem) close(respChan) }() // Worker Pool: sends requests to the API var wg sync.WaitGroup for i := 0; i < maxWorkers; i++ { wg.Add(1) go func() { defer wg.Done() for { select { case resp := <-respChan: fmt.Println(resp.Status) resp.Body.Close() sem <- true case err := <-respErrChan: log.Fatal(err) } } }() } wg.Wait() }
这种方法使用工作池在有限的时间内并发发送请求信号量,将并发请求数保持在系统限制内。响应处理也得到了改进,包括状态打印和主体关闭。与原始实现相比,该技术更加准确和可扩展。
以上是Go中如何高效处理并发HTTP请求?的详细内容。更多信息请关注PHP中文网其他相关文章!