golang http.client 并发请求无法立即关闭

这是我的代码 https://goplay.space/#z5J6i_EPWmx

功能为根据代理ip文件内容,对同一个地址进行代理验证

如果同时设置http.client timeout和transport dial timeout则会出现 socket too many open files 的错误。

我在程序中通过一个queueChanbufferd channel 控制同时请求数量。但是根据pprof调试和 /proc/pid/fd中的socket文件数量, 得出结论为旧的请求还未彻底关闭 新的请求又被创建最终导出的fd满了, 跟踪http源码之后发现这是goroutine泄露?同时nestat中有大量TIME_WAIT

如果只设置transport dial timeout,不设置http.client timeout 则goroutine数量和queueChan长度一致,fd数量也正常,但是netstat出现大量的ESTABLISHED, 并且请求超过timeout 也不结束

查了一些资料说频繁创建transport会出问题,那不同的protocol和proxy host能否复用tcp connection?

所以最终的问题是 当请求结束时如何立即关闭connection?

共 1 个回复


gratonos

http.Client创建一个就好,不要循环创建,官方文档有说明:“The Client's Transport typically has internal state (cached TCP connections), so Clients should be reused instead of created as needed. Clients are safe for concurrent use by multiple goroutines.”

# 0