Go高并发核心是控量、防耗尽、准错误处理与超时管理,需用context限超时、semaphore限并发、http.Transport调优连接池,并结构化日志追踪异常。
Go 语言原生支持高并发网络请求,核心不是“怎么加 goroutine”,而是“如何控制并发量、避免资源耗尽、正确处理错误和超时”。盲目起成百上千个 go http.Get() 很容易打垮目标服务或本地文件描述符耗尽。
用 sync.WaitGroup + goroutine 控制基础并发结构
这是最直接的并发模型,但必须配上限流和错误处理,否则只是把问题延迟暴露。
常见错误现象:too many open files(Linux 默认 ulimit -n 1024)、大量 context.DeadlineExceeded 或连接拒绝。
- 始终用
context.WithTimeout()或context.WithCancel()包裹请求,绝不依赖http.Client.Timeout单一设置 -
sync.WaitGroup的Add()必须在 goroutine 启动前调用,不能放 inside goroutine - 每个 goroutine 内部必须显式
defer wg.Done(),且确保无论成功失败都执行 - 示例片段:
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
resp, err := http.DefaultClient.Do(req.WithContext(ctx))
// ... 处理 resp/err
}(url)
}
wg.Wait()
用 semaphore(信号量)限制并发数,避免压垮服务
无限制并发等于拒绝服务攻击。生产环境必须硬性限流,推荐用 golang.org/x/sync/semaphore。
使用场景:爬虫、批量健康检查、第三方 API 批量调用(如每秒最多 10 请求)。