1. 现象
http请求时抛出"server closed idle connection"异常
2. 原因
keep-alive连接突然被服务端中断后(例如网络不稳定,服务端故障灯),客户端会抛出这样的异常,但net/http包并没有主动去重试http请求,官方给出的解释见地址github golang官方库的 issue-19943。大致原因是,当请求的METHOD为POST、DELETE、PUT等等,并不能确定请求是否具有幂等性,所以net/http包不会重试METHOD为上述类型的请求,代码如下
// net/http/request.go
func (r *Request) isReplayable() bool {
if r.Body == nil || r.Body == NoBody || r.GetBody != nil {
switch valueOrDefault(r.Method, "GET") {
case "GET", "HEAD", "OPTIONS", "TRACE":
return true
}
// The Idempotency-Key, while non-standard, is widely used to
// mean a POST or other request is idempotent. See
// golang.org/issue/19943#issuecomment-421092421
if r.Header.has("Idempotency-Key") || r.Header.has("X-Idempotency-Key") {
return true
}
}
return false
}
如果客户自己确认服务端的某个请求可以重试,可以在请求头中配置Idempotency-Key或者X-Idempotency-Key,net/http包会重试任何带有这种请求头的请求