应复用 http.Client 并配置 Transport 参数限流而非盲目启大量 goroutine设 MaxIdleConns 和 MaxIdleConnsPerHost 为 100、IdleConnTimeout 为 30s并用带缓冲 channel如 make(chan struct{}, 10)控制并发数。用 http.Client 控制并发别直接开几百个 go 语句开一堆 go downloadFile(url) 看似简单实际会瞬间打爆本地文件描述符、触发 DNS 超时、被目标站限流甚至封 IP。根本问题不在协程本身而在没管住底层 HTTP 连接和请求节奏。正确做法是复用 http.Client并配好 TransportMaxIdleConns 和 MaxIdleConnsPerHost 设为足够大比如 100避免频繁建连IdleConnTimeout 设短一点如 30s防连接堆积给每个 http.Request 加上 Context支持超时和取消示例关键片段client : http.Client{ Transport: http.Transport{ MaxIdleConns: 100, MaxIdleConnsPerHost: 100, IdleConnTimeout: 30 * time.Second, },}用 semaphore 或带缓冲 channel 限流不是靠 time.Sleeptime.Sleep 是假限流它不阻止 goroutine 创建只延迟执行内存和调度开销照旧。真正要控的是「同时发起的请求数」。推荐用带缓冲的 channel 模拟信号量立即学习“go语言免费学习笔记深入”初始化 sem : make(chan struct{}, 10) 表示最多 10 个并发每个下载前写入sem 下载完记得 -sem 归还额度注意别漏掉归还——尤其在错误路径里。漏了就卡死。下载失败时别忽略 resp.Body.Close()否则连接泄漏这是 Go 并发下载最隐蔽的泄漏点。哪怕 resp.StatusCode ! 200 或 err ! nil只要 resp 非 nilresp.Body 就必须关。 Felvin AI无代码市场只需一个提示快速构建应用程序