使用http 4次挥手排查http连接池请求eof问题

  1.问题:在使用golang httpclient进行周期性http请求时,偶发性出现eof等报错,http client请求代码如下:

        tr := &http.Transport{
    	TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		}
		
		client = &http.Client{Transport: tr, Timeout: 60 * time.Second}

简单的初始化一个client,然后进行请求

出现eof。

2.分析:网络搜索出现eof原因有一下几点

我们不存在并发问题排除5,读写超时时间golang均有默认设置排除3,正常多次手动请求结果均正常排除4.由于golang httpclient默认会开启连接复用,那么问题原因应是连接复用问题,如果是客户端主动断了连接,连接池应不能复用该连接除非有bug,另外就是服务端关闭了连接。

测试发现只有在睡眠5秒时会发生报错,小于5秒或者大于5秒均不会报错。检查服务端配置发现其keepalive时间刚好为5秒。

猜想服务端在第5秒时关闭连接,此时客户端刚好发起请求但是连接已关闭导致eof。如此分析http4次挥手

这里服务端主动关闭连接所以为4次挥手发起关闭连接的客户端。由4次挥手可见,客户端发起关闭连接后,服务端处于close_wait状态,并且可以继续发送数据,但是客户端并不会回复,推断这是eof发生的原因。

3.验证

进行抓包验证,如下图

可见237发出FIN包,并且252回应了ACK,此时252处于time_wait,继续发送了一次http请求,由于237此时已经无法响应,触发了eof。

4.结论

解决办法就很简单,周期性请求间隔不为5秒即可规避,但更好的方式是服务端keepalive的时间设得更长一点。同时,golang http客户端可以关闭链接复用,如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值