序
本文主要研究一下HttpClient的NoHttpResponseException
NoHttpResponseException
org/apache/http/NoHttpResponseException.java
代码语言:javascript复制/**
* Signals that the target server failed to respond with a valid HTTP response.
*
* @since 4.0
*/
public class NoHttpResponseException extends IOException {
private static final long serialVersionUID = -7658940387386078766L;
/**
* Creates a new NoHttpResponseException with the specified detail message.
*
* @param message exception message
*/
public NoHttpResponseException(final String message) {
super(HttpException.clean(message));
}
}
NoHttpResponseException继承了IOException,用于表示目标服务器没有返回一个正常的http response
DefaultHttpResponseParser
org/apache/http/impl/conn/DefaultHttpResponseParser.java
代码语言:javascript复制public class DefaultHttpResponseParser extends AbstractMessageParser<HttpResponse> {
private final Log log = LogFactory.getLog(getClass());
private final HttpResponseFactory responseFactory;
private final CharArrayBuffer lineBuf;
//......
@Override
protected HttpResponse parseHead(
final SessionInputBuffer sessionBuffer) throws IOException, HttpException {
//read out the HTTP status string
int count = 0;
ParserCursor cursor = null;
do {
// clear the buffer
this.lineBuf.clear();
final int i = sessionBuffer.readLine(this.lineBuf);
if (i == -1 && count == 0) {
// The server just dropped connection on us
throw new NoHttpResponseException("The target server failed to respond");
}
cursor = new ParserCursor(0, this.lineBuf.length());
if (lineParser.hasProtocolVersion(this.lineBuf, cursor)) {
// Got one
break;
} else if (i == -1 || reject(this.lineBuf, count)) {
// Giving up
throw new ProtocolException("The server failed to respond with a "
"valid HTTP response");
}
if (this.log.isDebugEnabled()) {
this.log.debug("Garbage in response: " this.lineBuf.toString());
}
count ;
} while(true);
//create the status line from the status string
final StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor);
return this.responseFactory.newHttpResponse(statusline, null);
}
protected boolean reject(final CharArrayBuffer line, final int count) {
return false;
}
}
DefaultHttpResponseParser继承了AbstractMessageParser,其parseHead方法读取sessionBuffer,若该数据为空则抛出NoHttpResponseException(“The target server failed to respond”)
小结
NoHttpResponseException继承了IOException,用于表示目标服务器没有返回一个正常的http response,一般是目标服务器负载太高处理不过来因而断开了连接,也有可能是目标服务器把这个空闲连接关闭了,而HttpClient则继续用这个连接发送请求则会读取不到正常的reponse,因而抛出NoHttpResponseException。大多数情况下,可以通过重试解决。另外针对因为keep-alive超时断开的,可以配置HttpClient的connTimeToLive值小于服务端的keepAlive值(通常是60s
)。
doc
- Exception handling
- 生产环境NoHttpResponseException异常排查记录