背景
了解一下,Go的client是怎么使用TCP链接的。
client 包 一次完整请求
client使用
http.Client{
Transport: &http.Transport{
DialContext: (&net.Dialer{
Timeout: 30 * time.Second, //连接超时时间
KeepAlive: 30 * time.Second, //连接保持超时时间
DualStack: true, //
}).DialContext,
MaxIdleConnsPerHost: 2,//每个host 最大空闲链接数
MaxIdleConns: 100, //client对与所有host最大空闲连接数总和
IdleConnTimeout: 90 * time.Second, //空闲连接在连接池中的超时时间
TLSHandshakeTimeout: 10 * time.Second, //TLS安全连接握手超时时间
ExpectContinueTimeout: 1 * time.Second, //发送完请求到接收到响应头的超时时间
},
//总的超时时间
Timeout: serv.GetTotalTimeout(),
}.Do(req)
发起流程
Do
func (c *Client) Do(req *Request) (*Response, error) {
//...
for {
//首次不会进入,如果需要重定向,会进入
if len(reqs) > 0 {
//...
}
reqs = append(reqs, req)
var err error
var didTimeout func() bool
// 调用send
if resp, didTimeout, err = c.send(req, deadline); err != nil {
if !deadline.IsZero() && didTimeout() {
err = &httpError{
err: err.Error() + " (Client.Timeout exceeded while awaiting headers)",
timeout: true,
}
}
return nil, uerr(err)
}
//检查是否需要重定向,如果不需要直接返回
var shouldRedirect bool
redirectMethod, shouldRedirect, includeBody = redirectBehavior(req.Method, resp, reqs[0])
if !shouldRe