[
https://issues.apache.org/jira/browse/HTTPCLIENT-1918?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16457158#comment-16457158
]
Santhosh Sheshasayanan edited comment on HTTPCLIENT-1918 at 4/27/18 10:17 PM:
------------------------------------------------------------------------------
Hi Oleg,
As per our code we are not doing any connection management. We are using the
"connectionpool" mechanism to handle connection request, request/response
handling, closing connection. We dont have any control over the connection.
Kindly look at the code below,
*//// All http client config*
private val *responseHandler* = new ResponseHandler[HttpResponse] {
def handleResponse(response: org.apache.http.HttpResponse): HttpResponse =
{ val statusLine = response.getStatusLine val body =
EntityUtils.toString(response.getEntity) val headers = Map((for (h <-
response.getAllHeaders) yield
{ h.getName -> h.getValue }
).toArray: _*)
HttpResponse(statusLine.getStatusCode, statusLine.getReasonPhrase, body,
headers)
}
}
private val *clientConnectionManager* =
{ val clientConnectionManager = new PoolingHttpClientConnectionManager
clientConnectionManager.setMaxTotal(cfg.connectionPoolSize)
clientConnectionManager.setDefaultMaxPerRoute(cfg.connectionPoolSize)
clientConnectionManager }
private val *httpParams* =
{ import org.apache.http.params.CoreConnectionPNames._ import
org.apache.http.params.CoreProtocolPNames._ val httpParams = new
BasicHttpParams httpParams.setParameter(USER_AGENT, "HTTP CLIENT
[%s]".format(cfg.httpClientName)) httpParams.setParameter(SO_TIMEOUT,
cfg.socketTimeout) httpParams.setParameter(CONNECTION_TIMEOUT,
cfg.connectionTimeout) DefaultHttpClient.setDefaultHttpParams(httpParams)
httpParams }
private val *httpRequestRetryHandler* =
{ new DefaultHttpRequestRetryHandler(1, false) }
private val *basicCredentialsProvider* =
{ val basicCredentialsProvider = new BasicCredentialsProvider
basicCredentialsProvider.setCredentials(AuthScope.ANY, new
UsernamePasswordCredentials(cfg.username, cfg.password))
basicCredentialsProvider }
private val *httpClient* =
{ info("[%s] Start".format(cfg.httpClientName)) val client: CloseableHttpClient
= HttpClients.custom() .setConnectionManager(clientConnectionManager)
.setRetryHandler(httpRequestRetryHandler)
.setDefaultCredentialsProvider(basicCredentialsProvider)
.evictExpiredConnections() .evictIdleConnections(5, TimeUnit.SECONDS) .build()
client }
///// HTTP Client code execution
try
{ httpUriRequest.setParams(httpParams) httpClient.execute(httpUriRequest,
responseHandler, localContext) }
catch {
case ex: Exception =>
{ warn("[%s] Executing HTTP %s %s failed with
exception".format(cfg.httpClientName, httpUriRequest.getMethod,
httpUriRequest.getURI), ex) ExceptionResult(ex) }
}
Thanks,
Santhosh S
was (Author: ssanthosh29):
Hi Oleg,
As per our code we are not doing any connection management. We are using the
"connectionpool" mechanism to handle connection request, request/response
handling, closing connection. We dont have any control over the connection.
Kindly look at the code below,
*//// All http client config*
private val *responseHandler* = new ResponseHandler[HttpResponse] {
def handleResponse(response: org.apache.http.HttpResponse): HttpResponse =
{ val statusLine = response.getStatusLine val body =
EntityUtils.toString(response.getEntity) val headers = Map((for (h <-
response.getAllHeaders) yield
{ h.getName -> h.getValue }
).toArray: _*)
HttpResponse(statusLine.getStatusCode, statusLine.getReasonPhrase, body,
headers)
}
}
private val *clientConnectionManager* =
{ val clientConnectionManager = new PoolingHttpClientConnectionManager
clientConnectionManager.setMaxTotal(cfg.connectionPoolSize)
clientConnectionManager.setDefaultMaxPerRoute(cfg.connectionPoolSize)
clientConnectionManager }
private val *httpParams* =
{ import org.apache.http.params.CoreConnectionPNames._ import
org.apache.http.params.CoreProtocolPNames._ val httpParams = new
BasicHttpParams httpParams.setParameter(USER_AGENT, "HTTP CLIENT
[%s]".format(cfg.httpClientName)) httpParams.setParameter(SO_TIMEOUT,
cfg.socketTimeout) httpParams.setParameter(CONNECTION_TIMEOUT,
cfg.connectionTimeout) DefaultHttpClient.setDefaultHttpParams(httpParams)
httpParams }
private val *httpRequestRetryHandler* =
{ new DefaultHttpRequestRetryHandler(1, false) }
private val *basicCredentialsProvider* =
{ val basicCredentialsProvider = new BasicCredentialsProvider
basicCredentialsProvider.setCredentials(AuthScope.ANY, new
UsernamePasswordCredentials(cfg.username, cfg.password))
basicCredentialsProvider }
private val *httpClient* =
{ info("[%s] Start".format(cfg.httpClientName)) val client: CloseableHttpClient
= HttpClients.custom() .setConnectionManager(clientConnectionManager)
.setRetryHandler(httpRequestRetryHandler)
.setDefaultCredentialsProvider(basicCredentialsProvider)
.evictExpiredConnections() .evictIdleConnections(5, TimeUnit.SECONDS) .build()
client }
///// HTTP Client code execution
try
{ httpUriRequest.setParams(httpParams) httpClient.execute(httpUriRequest,
responseHandler, localContext) }
catch {
case ex: Exception =>
{ warn("[%s] Executing HTTP %s %s failed with
exception".format(cfg.httpClientName, httpUriRequest.getMethod,
httpUriRequest.getURI), ex) ExceptionResult(ex) }
}
Thanks,
Santhosh S
> CLOSE_WAIT issue in HttpClient
> ------------------------------
>
> Key: HTTPCLIENT-1918
> URL: https://issues.apache.org/jira/browse/HTTPCLIENT-1918
> Project: HttpComponents HttpClient
> Issue Type: Bug
> Components: HttpClient (async)
> Affects Versions: 4.5.5
> Reporter: Santhosh Sheshasayanan
> Priority: Major
> Attachments: Capture-0.PNG, Capture-1.PNG, Capture.PNG,
> IdleConnectionMonitorThread.java, close_wait.log, frt-acs03-netstat.log
>
>
> We are facing CLOSE_WAIT issue in our production system on heavy load. We are
> using Apache's httpClient 4.5.5 and httpcore 4.4.9 in our code. Sometime the
> server sends half of the data; sometime server sends no data and close the
> connection at their end. Now, httpclient puts the socket connection to
> CLOSE_WAIT indefinitely.
> We tried the following but nothing helped us.
> * Set TTL to 1 minutes in PoolingHttpClientConnectionManager
> * Used the following methods
> ** evictExpiredConnections()
> ** evictIdleConnections(5, TimeUnit._SECONDS_)
> **
> [https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html|https://apac01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fhc.apache.org%2Fhttpcomponents-client-ga%2Ftutorial%2Fhtml%2Fconnmgmt.html&data=02%7C01%7Ckumaran.ae%40hcl.com%7Ce88009e18e4145e27ebc08d5aa2ae38c%7C189de737c93a4f5a8b686f4ca9941912%7C0%7C0%7C636602023532727032&sdata=2s0L63M%2F%2F7slLF3Uhx2Ly2SHSiknz0hA4fF8wDvxbS0%3D&reserved=0]
> *** Topic "2.5. Connection eviction policy"
> *** Topic "2.6. Connection keep alive strategy"
> Later, we found the method "setValidateAfterInactivity". Its description
> says "This check helps detect connections that have become stale
> (half-closed) while kept inactive in the pool". So we thought it will help us
> to detect and close the socket which are in "CLOSE_WAIT" state. But it did
> not help us.
> Problem here, The HTTP client puts the socket into "CLOSE_WAIT" state and
> waiting for the signal from server to close the socket. But the server closed
> the connection already. Please suggest us how to handle/resolve the issue?
>
> +*Scala Code Snippet*+
> private val clientConnectionManager =
> { val clientConnectionManager = new PoolingHttpClientConnectionManager(1,
> java.util.concurrent.TimeUnit.MINUTES);
> clientConnectionManager.setMaxTotal(cfg.connectionPoolSize)
> clientConnectionManager.setDefaultMaxPerRoute(cfg.connectionPoolSize)
> clientConnectionManager.setValidateAfterInactivity(30000);
> clientConnectionManager }
> *val monitorThread = new
> IdleConnectionMonitorThread(clientConnectionManager);*
> *monitorThread.start();*
>
>
>
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]