如何使用Golang实现并发HTTP请求_同时获取多个接口数据
发布时间 - 2026-01-02 00:00:00 点击率:次Go 并发 HTTP 请求需控制并发数(20–50)、使用 context 统一超时、通过 channel 安全收集结果;避免盲目启大量 goroutine,推荐 semaphore 或带缓冲 channel 限流,并用结构体封装结果防止竞态。
用 Go 实现并发 HTTP 请求,核心是结合 goroutine 和 channel 控制并发流程,同时避免资源耗尽和超时堆积。关键不是“越多越快”,而是合理控制并发数、统一处理错误与超时、安全收集结果。
控制并发数量,防止压垮服务或自身
直接为每个请求起一个 goroutine 容易失控(比如 1000 个 URL 启 1000 个 goroutine),推荐使用带缓冲的 channel 或 semaphore 模式限制并发数:
- 用
make(chan struct{}, N)作为信号量:每次发请求前先写入一个占位符,请求结束再读出,自然限流 - 或用第三方库如
golang.org/x/sync/semaphore,语义更清晰 - 常见合理值:20–50(取决于目标接口承载力和本地网络/文件描述符限制)
每个请求必须带上下文(context)超时
单个请求卡住会拖慢整个批次。务必用 context.WithTimeout 或 context.WithDeadline 包裹请求:
- 不要只靠
http.Client.Timeout,它不覆盖 DNS 解析、TLS 握手等阶段 - 推荐写法:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second),并在 defer 中调用cancel() - 把
ctx传给http.NewRequestWithContext,再交给client.Do
用 channel 安全收集结果,区分成功与失败
避免多个 goroutine 写同一 slice 引发竞态。建议定义结构体封装结果,并用 channel 统一接收:
type Result struct {
URL string
Data []byte
Err error
Status int
}- 启动 N 个 goroutine,每个做完后把
Result发到同一个chan R
esult - 主 goroutine 用
for i := 0; i 循环接收,确保收齐 - 可额外加一个
donechannel 或sync.WaitGroup辅助判断完成
完整轻量示例(无依赖,开箱即用)
以下代码并发请求 3 个 URL,最大并发 2,每请求 3 秒超时:
func fetchURL(ctx context.Context, url string, sem chan struct{}) Result {
sem <- struct{}{} // 获取令牌
defer func() { <-sem }() // 释放令牌
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
client := &http.Client{Timeout: 3 * time.Second}
resp, err := client.Do(req)
if err != nil {
return Result{URL: url, Err: err}
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
return Result{URL: url, Data: data, Status: resp.StatusCode}}
func main() {
urls := []string{"https://www./link/5f69e19efaba426d62faeab93c308f5c", "https://www./link/ef246753a70fce661e16668898810624", "https://www./link/8c4b0479f20772cb9b68cf5f161d1e6f"}
sem := make(chan struct{}, 2)
ch := make(chan Result, len(urls))
for _, u := range urls {
go func(url string) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
ch <- fetchURL(ctx, url, sem)
}(u)
}
results := make([]Result, 0, len(urls))
for i := 0; i < len(urls); i++ {
results = append(results, <-ch)
}
for _, r := range results {
if r.Err != nil {
fmt.Printf("❌ %s → %v\n", r.URL, r.Err)
} else {
fmt.Printf("✅ %s → %d bytes, status %d\n", r.URL, len(r.Data), r.Status)
}
}}
不复杂但容易忽略细节:限流、上下文、结果收集三者缺一不可。实际项目中可进一步封装成可复用函数,支持自定义 Header、重试、熔断等。
# go
# golang
# app
# ai
# dns
# 并发请求
# String
# for
# 封装
# 结构体
# 循环
# 接口
# 堆
# Struct
# len
# 并发
# channel
# background
# http
# https
# 令牌
# 信号量
# 多个
# 推荐使用
# 并在
# 自定义
# 越多
# 第三方
# 它不
# 越快
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel Seeder填充数据教程_Laravel模型工厂Factory使用
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
Laravel如何使用查询构建器?(Query Builder高级用法)
制作电商网页,电商供应链怎么做?
Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
javascript中的try catch异常捕获机制用法分析
如何在阿里云完成域名注册与建站?
QQ浏览器网页版登录入口 个人中心在线进入
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
Linux系统运维自动化项目教程_Ansible批量管理实战
如何快速生成可下载的建站源码工具?
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
常州企业网站制作公司,全国继续教育网怎么登录?
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
历史网站制作软件,华为如何找回被删除的网站?
如何快速生成ASP一键建站模板并优化安全性?
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
php json中文编码为null的解决办法
SQL查询语句优化的实用方法总结
如何用VPS主机快速搭建个人网站?
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
如何自定义建站之星模板颜色并下载新样式?
如何在服务器上三步完成建站并提升流量?
Thinkphp 中 distinct 的用法解析
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
Python高阶函数应用_函数作为参数说明【指导】
Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】
WEB开发之注册页面验证码倒计时代码的实现
如何快速上传自定义模板至建站之星?
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
如何在云主机上快速搭建多站点网站?
在线制作视频的网站有哪些,电脑如何制作视频短片?
使用Dockerfile构建java web环境
做企业网站制作流程,企业网站制作基本流程有哪些?
千库网官网入口推荐 千库网设计创意平台入口
如何将凡科建站内容保存为本地文件?
Laravel distinct去重查询_Laravel Eloquent去重方法
linux写shell需要注意的问题(必看)
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
Laravel如何为API编写文档_Laravel API文档生成与维护方法
网站制作软件免费下载安装,有哪些免费下载的软件网站?
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
如何在香港服务器上快速搭建免备案网站?
如何在HTML表单中获取用户输入并结合JavaScript动态控制复利计算循环


esult