大佬们,用 go 同时发起几万个 get 请求,怎么优化请求函数呢?

2022-09-22 09:41:27 +08:00
 biuyixia

代码如下:

func check_url(url string) {
    client := &http.Client{
        Timeout: time.Second * 5,
    }
    req, _ := http.NewRequest("GET", url, nil)
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36")
    resp, err := client.Do(req)
    if err == nil {
        defer resp.Body.Close()

        status := resp.Status
        if strings.Contains(status, "200") {
            fmt.Println(url,"===请求成功===")
        }
    }
}

小弟刚学 go ,我需要同时并发几万个 url 请求,调用 check_url 函数,发现有时候明明可以访问的端口,却报 context deadline exceeded (Client.Timeout exceeded while awaiting headers) 错误,怎么优化这个 check_url 函数呢?

4795 次点击
所在节点    程序员
37 条回复
biuyixia
2022-09-22 12:38:52 +08:00
@sadfQED2 谢大佬。那就 client 共用。
wheeler
2022-09-22 13:08:33 +08:00
@sadfQED2 #18 keepalive 不是 transport 维护的吗?不指定 transport 都是复用默认的 transport 吧?
wheeler
2022-09-22 13:10:43 +08:00
@wheeler #22

// Transport specifies the mechanism by which individual
HTTP requests are made.
If nil, DefaultTransport is used.

https://pkg.go.dev/net/http
a132811
2022-09-22 13:34:42 +08:00
Client.Timeout exceeded while awaiting headers
可能服务端超时、或者带宽不够吧。
1. 确认你的网络有没有瓶颈
2. 确认你的服务真实并发:用 ab/vegeta/gowrk 等工具压测一下
monkeyWie
2022-09-22 13:37:04 +08:00
@aino #19 能啊,上 nio 、或者直接 netty
derrick1
2022-09-22 13:47:36 +08:00
也可能是目标服务器瓶颈, 或者 seers 说的问题
biuyixia
2022-09-22 14:02:17 +08:00
@derrick1 好的大佬。估计就是了
zbatman
2022-09-22 15:26:27 +08:00
刑啊
sadfQED2
2022-09-22 15:30:09 +08:00
@wheeler 额,确实是。是我记错了
lysS
2022-09-22 15:34:09 +08:00
接口扫描是吧?不用 GET 、用 HEAD ,更好的方法其实还是用 tcp 请求
lysS
2022-09-22 15:37:38 +08:00
还有啊,扫描不同的地址,连接池是没用的
iceiceice
2022-09-22 15:39:22 +08:00
用 fasthttp
aladdinding
2022-09-22 16:03:43 +08:00
用同一个 client transport 调节大点
bthulu
2022-09-22 16:40:31 +08:00
带宽打满了吧, 后面的请求只能排队了, 然后就超时了
biuyixia
2022-09-30 09:10:11 +08:00
@seers 大佬,我想问问你说的 open file 数是什么?还有 ulimit ,跟 http 请求有关系吗,小弟刚学。请指教

你说的第二个,最后 err 打印下,那个异常端口就是报的 context deadline exceeded (Client.Timeout exceeded while awaiting headers)
seers
2022-09-30 14:29:04 +08:00
@biuyixia 不严谨简单的说,在 Linux 里面发起一个 HTTP 请求等同于打开一个文件(一切皆文件,Unix 哲学),系统打开文件数是有上限的,由 ulimit 查看修改,如果限制数太低,后面发起的连接就会进入队列,然后进入队列的请求会超时报错,当然这只是猜测,还需要你多分析。
biuyixia
2022-10-08 15:25:27 +08:00
@seers 谢谢大佬。我这个 windows

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/882038

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX