Go:HTTP长连接
Go:HTTP长连接
Go:HTTP长连接
一、演示
package mainimport ("fmt""io""io/ioutil""log""net""net/http""net/url""sync""time"
)var (client *http.Clientonce sync.Once
)func CreateHTTPClient() *http.Client {// 使用单例创建clientonce.Do(func() {client = &http.Client{Transport: &http.Transport{DialContext: (&net.Dialer{Timeout: 30 * time.Second,KeepAlive: 30 * time.Second,}).DialContext,MaxIdleConns: 100, // 最大连接数,默认0无穷大MaxIdleConnsPerHost: 100, // 对每个host的最大连接数量(MaxIdleConnsPerHost<=MaxIdleConns)IdleConnTimeout: 90 * time.Second, // 多长时间未使用自动关闭连接},}})return client
}func main() {client := CreateHTTPClient()req, err := http.NewRequest("get", "https://www.baidu.com", nil)if err != nil {log.Fatal(err)}res, err := client.Do(req)if err != nil {log.Fatal(err)}io.Copy(ioutil.Discard, res.Body)res.Body.Close()
}
二、源码分析
(一)Transport默认实现
var DefaultTransport RoundTripper = &Transport{Proxy: ProxyFromEnvironment,DialContext: (&net.Dialer{Timeout: 30 * time.Second,KeepAlive: 30 * time.Second,DualStack: true,}).DialContext,MaxIdleConns: 100,IdleConnTimeout: 90 * time.Second,TLSHandshakeTimeout: 10 * time.Second,ExpectContinueTimeout: 1 * time.Second,
}
(二)字段解析
1、MaxIdleConns
最大连接数,默认0无限
2、MaxIdleConnsPerHost
const DefaultMaxIdleConnsPerHost = 2
同一个host最大连接数(MaxIdleConnsPerHost<=MaxIdleConns),如果不设置默认使用DefaultMaxIdleConnsPerHost
3、IdleConnTimeout
多长时间未使用自动关闭连接
三、注意
(一)请求头Connection
http1.0默认短连接,需要连接复用需要显式添加头Connection: keep-alive
http1.1默认长连接,默认:Connection: keep-alive,如果需要当前请求完成关闭连接添加Connection: close
(二)关于响应body数据
只要请求响应包含响应body必须读取出来,否则无法复用连接。如果响应数据不需要可以使用下面示例丢弃响应
io.Copy(ioutil.Discard, res.Body)
四、参考
- go net/http Client使用——长连接客户端的使用