使用Goroutine和sync.WaitGroup实现并发HTTP请求,通过带缓冲channel控制最大并发数,结合context.WithTimeout管理超时,自定义http.Transport复用连接以提升性能,构建高效稳定的并发处理程序。

在Go语言中处理并发HTTP请求是其核心优势之一,得益于Goroutine和高效的网络库。构建一个能高效处理并发HTTP请求的项目,关键在于合理利用标准库、控制并发数量、避免资源竞争,并做好错误处理与超时管理。
使用Goroutine发起并发请求
Go的net/http包配合Goroutine可以轻松实现高并发请求。每个请求在一个独立的Goroutine中执行,主线程不阻塞。
示例:并发获取多个URL内容
package mainimport ( "fmt" "io/ioutil" "net/http" "sync" )
func fetch(url string, wg *sync.WaitGroup) { defer wg.Done() resp, err := http.Get(url) if err != nil { fmt.Printf("Error fetching %s: %v\n", url, err) return } defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body) fmt.Printf("Fetched %d bytes from %s\n", len(body), url)}
立即学习“go语言免费学习笔记(深入)”;
TeemIp - IPAM and DDI solution下载TeemIp是一个免费、开源、基于WEB的IP地址管理(IPAM)工具,提供全面的IP管理功能。它允许您管理IPv4、IPv6和DNS空间:跟踪用户请求,发现和分配IP,管理您的IP计划、子网空间、区域和DNS记录,符合最佳的DDI实践。同时,TeemIp的配置管理数据库(CMDB)允许您管理您的IT库存并将您的配置项(CIs)与它们使用的IP关联起来。项目源代码位于https://github.com/TeemIP
func main() { urls := []string{ "https://www.php.cn/link/5f69e19efaba426d62faeab93c308f5c", "https://www.php.cn/link/c2148796071914983ed6b6e9dbbff735", "https://www.php.cn/link/5f4d36824abbbe0b96729728d035a7ae", }
var wg sync.WaitGroup for _, url := range urls { wg.Add(1) go fetch(url, &wg) } wg.Wait()}
限制并发数避免系统过载
无限制地启动Goroutine可能导致内存溢出或被目标服务器封禁。使用带缓冲的channel可有效控制最大并发数。
func limitedFetch(urls []string) {
const maxConcurrency = 5
sem := make(chan struct{}, maxConcurrency)
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
sem <- struct{}{} // 获取令牌
defer func() { <-sem }() // 释放令牌
resp, err := http.Get(u)
if err != nil {
fmt.Printf("Failed: %s - %v\n", u, err)
return
}
defer resp.Body.Close()
fmt.Printf("Success: %s (Status: %d)\n", u, resp.StatusCode)
}(url)
}
wg.Wait()}
使用Context控制超时和取消
长时间挂起的请求会浪费资源。通过context.WithTimeout设置请求级超时,提升系统响应性。
func fetchWithTimeout(url string, timeoutSec int) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeoutSec)*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
return nil}
复用连接提升性能
频繁创建TCP连接开销大。通过自定义Transport启用长连接并限制空闲连接数,显著提高吞吐量。
client := &http.Client{
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 30 * time.Second,
},
Timeout: 10 * time.Second,
}
基本上就这些。结合Goroutine、channel、context和优化的HTTP客户端配置,就能构建稳定高效的并发HTTP处理程序。实际项目中还可加入重试机制、日志记录和结果收集等功能。不复杂但容易忽略细节。










