golang/go https配置中常见的几个超时时间配置的作用
背景: 经常有同事搞混golang/go中http相关几个超时配置的作用,所以记录下这几个超时配置的作用。
备注:下面的配置只针对http 1.1,http2.0可能略有不同
通过WireShark抓包获取的基本信息
总览
角色 | 字段 | 含义 | 备注 |
---|---|---|---|
client | Client.Timeout | 从建链到读完响应体的总超时时间,0表示不设置超时时间 | 包括抓包信息中的"tcp握手"+“tls证书交换”+“业务报文” |
client | Transport.TLSHandshakeTimeout | TLS证书交换总超时时间 | 客户端错误日志:net/http: TLS handshake timeout |
client | Transport.ResponseHeaderTimeout | 等待服务端响应的超时时间 | 客户端错误日志:net/http: timeout awaiting response headers |
client | Transport.IdleConnTimeout | 链路空闲超时时间,超时后自动断链 | |
client | Transport.ExpectContinueTimeout | 控制 HTTP 客户端在发送 Expect: 100-continue 头后,等待服务器 100 Continue 响应的最大时长,一般用于大文件上传 | |
client | Dialer.Timeout | 建链超时时间,这个超时时间会设置为建链的context. | |
client | Dialer.Deadline | 和Dialer.Timeout 功能类似,是个具体的时间点. | |
client | Dialer.KeepAlive | tcp keepAlive超时时间和周期. 如果链路在keepAlive时间段内没有业务报文,连接层会发送keepalive存活探测报文,如果连续9次没有对端没有响应,则认为此链路已经过时,关闭端链接。 | |
Server | Server.ReadTimeout | 服务端收到请求后读取header和body的超时时间 | |
Server | Server.ReadHeaderTimeout | 服务端收到请求后读取header的超时时间 | |
Server | Server.WriteTimeout | 服务端写入响应体的超时时间 | |
Server | Server.IdleTimeout | 链路空闲超时时间。 |
Transport.TLSHandshakeTimeout
tls握手超时时间.在server端建链部分sleep 10s,将Transport.TLSHandshakeTimeout
设置为6s,抓包发现6s后超时断链。
Transport.ResponseHeaderTimeout
请求发送后,等待服务端响应的时间.因为此时链接已经建立,通常是因为业务处理超时导致.
设置为3s
Transport.IdleConnTimeout
链路空闲超时时间.
设置为3s
Transport.ExpectContinueTimeout
控制 HTTP 客户端在发送 Expect: 100-continue 头后,等待服务器 100 Continue 响应的最大时长,一般用于大文件上传.
Dialer.Timeout
建链超时时间,这个超时时间会设置为建链的context.
func (d *Dialer) deadline(ctx context.Context, now time.Time) (earliest time.Time) {
if d.Timeout != 0 { // including negative, for historical reasons // Dialer.Timeout
earliest = now.Add(d.Timeout) // 当前时间加上Dialer.Timeout
}
if d, ok := ctx.Deadline(); ok {
earliest = minNonzeroTime(earliest, d) // 取earliest和ctx超时时间中两者中的小值
}
return minNonzeroTime(earliest, d.Deadline)
}
func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error) {
//...
deadline := d.deadline(ctx, time.Now())
if !deadline.IsZero() {
testHookStepTime()
if d, ok := ctx.Deadline(); !ok || deadline.Before(d) {
subCtx, cancel := context.WithDeadline(ctx, deadline) // 设置给context
defer cancel()
ctx = subCtx
}
}
//...
}
Dialer.Deadline
和Dialer.Timeout
功能类似,是个具体的时间点.
Dialer.KeepAlive
tcp keepAlive超时时间和周期. 如果链路在keepAlive时间段内没有业务报文,连接层会发送keepalive存活探测报文,如果连续9次没有对端没有响应,则认为此链路已经过时,关闭端链接。
Server.ReadTimeout
服务端收到请求后读取header和body的超时时间
Server.ReadHeaderTimeout
服务端收到请求后读取header的超时时间
Server.WriteTimeout
服务端写入响应体的超时时间
Server.IdleTimeout
链路空闲超时时间。
设置为3s,服务端主动断链。