0

0

Go语言并发请求接口怎么做_Golang高并发请求实战

P粉602998670

P粉602998670

发布时间:2026-01-19 14:24:08

|

336人浏览过

|

来源于php中文网

原创

应使用带缓冲的channel或semaphore控制并发数,而非无限制启动goroutine;sync.WaitGroup仅负责等待完成,真正的限速需通过make(chan struct{}, 10)等信号量机制实现。

go语言并发请求接口怎么做_golang高并发请求实战

goroutine + WaitGroup 控制并发数,别直接起成百上千个

Go 启动协程成本低,但不加限制地 go request() 一百次,可能瞬间打爆目标接口或本地文件描述符。关键不是“能不能并发”,而是“怎么安全控速”。sync.WaitGroup 负责等待全部完成,而真正控并发得靠带缓冲的 channelsemaphore

  • make(chan struct{}, 10) 做信号量:每次请求前 sem ,结束后 ,天然限流 10 并发
  • 别把 http.Client 创建放在 goroutine 里——复用一个实例,否则 DNS 缓存、连接池全失效
  • context.WithTimeout 必须设,否则单个失败请求可能卡死整个批次
sem := make(chan struct{}, 5) // 限制 5 并发
var wg sync.WaitGroup
for _, url := range urls {
    wg.Add(1)
    go func(u string) {
        defer wg.Done()
        sem <- struct{}{} // 获取令牌
        defer func() { <-sem }() // 释放令牌
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()

    req, _ := http.NewRequestWithContext(ctx, "GET", u, nil)
    resp, err := client.Do(req)
    if err != nil {
        log.Printf("fail %s: %v", u, err)
        return
    }
    resp.Body.Close()
}(url)

} wg.Wait()

http.Transport 不调优 = 并发再高也白搭

默认 http.DefaultClient 的 Transport 对并发极其保守:最多 100 个空闲连接、每 host 2 个连接、30 秒 idle timeout。压测时经常看到大量 net/http: request canceled (Client.Timeout exceeded while awaiting headers),其实不是超时,是连接被复用阻塞了。

  • MaxIdleConnsMaxIdleConnsPerHost 至少设到 200+,尤其目标 host 少的时候
  • IdleConnTimeout 建议 30–90 秒,太短导致频繁建连,太长占着连接不放
  • ForceAttemptHTTP2: true(Go 1.12+ 默认开启,但显式写上更安心)
client := &http.Client{
    Transport: &http.Transport{
        MaxIdleConns:        200,
        MaxIdleConnsPerHost: 200,
        IdleConnTimeout:     60 * time.Second,
        ForceAttemptHTTP2:   true,
    },
}

批量请求失败后怎么重试又不雪崩?用带退避的 Backoff

直接 for-loop 重试 3 次?网络抖动时所有请求在同一毫秒重试,流量翻三倍。得用指数退避(exponential backoff),且每个请求独立退避,避免同步重试。

  • 别手写 time.Sleep(time.Second * 1 ——用 github.com/cenkalti/backoff/v4 更稳
  • 只对 5xx 和部分 429 重试,4xx(如 400、401)基本是客户端错,重试无意义
  • 重试次数建议 ≤3,总耗时控制在原始 timeout 内,否则拖垮整批
operation := func() error {
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    if resp.StatusCode >= 500 || resp.StatusCode == 429 {
        return fmt.Errorf("server error: %d", resp.StatusCode)
    }
    return nil
}

err := backoff.Retry(operation, backoff.WithContext( backoff.NewExponentialBackOff(), ctx, ))

别忽略 DNS 和 TLS 握手开销——本地缓存和复用很重要

高频请求同一域名时,反复解析 DNS、建立 TLS 连接会吃掉大量时间。Go 默认不缓存 DNS 结果(除非启用了 GODEBUG=http2client=0 这类非标方式),TLS 会话复用也依赖 Transport 配置。

讯飞智作-虚拟主播
讯飞智作-虚拟主播

讯飞智作是一款集AI配音、虚拟人视频生成、PPT生成视频、虚拟人定制等多功能的AI音视频生产平台。已广泛应用于媒体、教育、短视频等领域。

下载

立即学习go语言免费学习笔记(深入)”;

  • net.Resolver 自建内存缓存 DNS,TTL 按实际服务稳定性设(比如 5 分钟)
  • Transport.TLSClientConfig 中启用 SessionTicketsDisabled: false(默认已是 false,但显式确认)
  • 如果目标 API 支持 HTTP/2,确保服务端没禁用 ALPN,否则降级 HTTP/1.1 会损失连接复用能力

并发请求不是堆 go 关键字,是平衡 transport 层、网络层、业务错误处理的系统动作。最容易被跳过的其实是 DNS 缓存和 TLS 复用——它们不报错,但让 QPS 卡在 200 上不去,排查时却总先怀疑代码逻辑。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1023

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

66

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

442

2025.12.29

Go中Type关键字的用法
Go中Type关键字的用法

Go中Type关键字的用法有定义新的类型别名或者创建新的结构体类型。本专题为大家提供Go相关的文章、下载、课程内容,供大家免费下载体验。

234

2023.09.06

go怎么实现链表
go怎么实现链表

go通过定义一个节点结构体、定义一个链表结构体、定义一些方法来操作链表、实现一个方法来删除链表中的一个节点和实现一个方法来打印链表中的所有节点的方法实现链表。

444

2023.09.25

go语言编程软件有哪些
go语言编程软件有哪些

go语言编程软件有Go编译器、Go开发环境、Go包管理器、Go测试框架、Go文档生成器、Go代码质量工具和Go性能分析工具等。本专题为大家提供go语言相关的文章、下载、课程内容,供大家免费下载体验。

247

2023.10.13

0基础如何学go语言
0基础如何学go语言

0基础学习Go语言需要分阶段进行,从基础知识到实践项目,逐步深入。php中文网给大家带来了go语言相关的教程以及文章,欢迎大家前来学习。

698

2023.10.26

Go语言实现运算符重载有哪些方法
Go语言实现运算符重载有哪些方法

Go语言不支持运算符重载,但可以通过一些方法来模拟运算符重载的效果。使用函数重载来模拟运算符重载,可以为不同的类型定义不同的函数,以实现类似运算符重载的效果,通过函数重载,可以为不同的类型实现不同的操作。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

194

2024.02.23

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

3

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.9万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号