-
Notifications
You must be signed in to change notification settings - Fork 618
Closed
Description
In my application I have random connection errors like this:
ClickHouseStatementImpl - Error during connection to ru.yandex.clickhouse.settings.ClickHouseProperties@785d9e37, reporting failure to data source, message: localhost:8123 failed to respond
org.apache.http.NoHttpResponseException: localhost:8123 failed to respond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:143)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
(I've modified the code to print the stacktrace in ClickHouseStatementImpl)
I think the root cause is that in some rare cases, Apache Http client doesn't detect a connection closed by the server (half-closed socket). I have a Wireshark capture which confirms this.
I've seen that the server returns how long it will keep the connection open but it doesn't seem to be used client side:
POST /?compress=1&extremes=0&database=default HTTP/1.1
Content-Length: 55
Content-Type: text/plain; charset=UTF-8
Host: xxxxxx:8123
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_152)
select timezone() FORMAT TabSeparatedWithNamesAndTypes;HTTP/1.1 200 OK
Date: Mon, 14 Jan 2019 08:04:41 GMT
Connection: Keep-Alive
Content-Type: text/tab-separated-values; charset=UTF-8
X-ClickHouse-Server-Display-Name: xxxxxxxxx
Transfer-Encoding: chunked
Keep-Alive: timeout=3
(...)
and
private ConnectionKeepAliveStrategy createKeepAliveStrategy() {
return new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse httpResponse, HttpContext httpContext) {
// in case of errors keep-alive not always works. close connection just in case
if (httpResponse.getStatusLine().getStatusCode() != HttpURLConnection.HTTP_OK) {
return -1;
}
HeaderElementIterator it = new BasicHeaderElementIterator(
httpResponse.headerIterator(HTTP.CONN_DIRECTIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
//String value = he.getValue();
if (param != null && param.equalsIgnoreCase(HTTP.CONN_KEEP_ALIVE)) {
return properties.getKeepAliveTimeout();
}
}
return -1;
}
};
}
So, shouldn't it be better to parse 'Keep-Alive: timeout=3' to get the keep-alive duration, and if it fails, use properties.getKeepAliveTimeout() ?
esukanovic, HuangXiaoyu3331 and ADingDing