在使用httpclient的时候,偶尔能遇到 NoHttpResponseException 这个异常。
根据这个异常的一些信息,感觉起来很像是网络的因素导致,但是其实不是的,主要是因为以下原因导致:
1,nginx并发压力非常大的时候,排队都来不及处理了,nginx直接丢弃了,这个时候会报这个错误。
2,还有一种情况,网上没有进行任何报道,那是在 nginx reload 的时候,假如 httpclient 刚好在快速的进行请求,这个时候就会报这个异常。这是因为:nginx reload不会对现有的请求连接进行中断,但是对于keepalive的连接,假如刚好没有在进行数据传输,nginx会认为该连接已经请求完毕,所以就主动关闭了,而几乎在同时,httpclient还没有获得主动关闭的响应,于是认为该连接是可用的,用这个连接发送数据的时候,就会收到这个异常。
对于第二个情况,有一篇文章这么讲道:https://github.com/alibaba/tengine/issues/1074 ,但是对于nginx core不是随便人都能改的,同时这么改了后也不知是否有其他副作用,总归解决办法不是特别理想。
经过查找资料以及分析,大家都在说可以用重试的机制来解决,从上述2种原因来看,也确实重试是最好的解决办法,那么对于 httpclient 来讲,怎么实现重试呢?下面贴一段代码:
HttpClientBuilder.create().setRetryHandler((exception, executionCount, context) -> {
if (executionCount > 1) {
return false;
}
if(exception instanceof NoHttpResponseException) {
log.info("NoHttpResponseException occured, will retry request");
return true;
}
return false;
}).build();
以上的代码对于重试,只是用了最简单重试,具体复杂的重试大家可以自行设计。