HTTPClient请求超时,但仍将响应映射到另一个请求

时间:2019-03-05 08:02:42

标签: java apache httpclient apache-httpclient-4.x

我在生产环境中遇到一个奇怪的错误。使用HttpClient 4.2.3,我们将请求从服务器(A)发送到另一个服务器(B)。由于这是生产环境,因此请求量非常大,有时服务器B在给定的指定时间内没有给出响应,并且由于我们收到了SocketTimeoutException。现在,此请求在我们的环境中已超时,但是在服务器B准备好响应后的一段时间后,该请求将追加到其他请求。因此,对于我们的环境的超时请求,但是当服务器B中的另一个响应准备就绪时,它将映射到服务器A的任何请求。

我认为在executeHTTPconnection方法中,我们需要关闭连接,但是我不确定还是有其他方法。

public String A(String request) throws AException
{
try
{
  fusionRes = this.protocolHandler.processStar(this.starhomeUrl, request, "application/json");
 ...
}
catch (IntegrationException e)
{
  isError = true;
  exceptionText = e.getMessage();
  if (e.getStatusCode() == 408)
  {             }
  else
  {
     response = new Response();
    response.setErrorDescription("Internal Server Error");
    response.setResponseCode(500);
    Res = new Gson().toJson(response);
  }
}
finally
{
  asyncLoggerService.execute(new FusionAsyncTraceTask("FUSION", startTime, System.currentTimeMillis(), request, this.starhomeUrl, isError, exceptionText, fusionRes));
}
return Res;
}

方法processStar

public String processStar(String resourceUrl, String reqXMLMessage, String contentType)
throws IntegrationException
{

HttpPost postMethod = null;
String responseData = null;
HttpResponse httpResponse = null;
InputStream is = null;
try
{
  this.httpClient = this.httpConnectionFacade.getHttpClient();            
  httpResponse = executeHTTPconnection(this.httpClient, postMethod, resourceUrl);
  int statusCode = httpResponse.getStatusLine().getStatusCode();
  if ((statusCode == 200) || (statusCode == 400) || (statusCode == 201) || (statusCode == 404) || (statusCode == 500) || (statusCode == 408) || (statusCode == 401) || (statusCode == 403) || (statusCode == 503))
  {
    is = httpResponse.getEntity().getContent();
    BufferedInputStream bufferedInputStream = new BufferedInputStream(is);
    responseData = HttpConnectionUtil.readResponseData(bufferedInputStream, resourceUrl);
  }
  else
  {
    log.error("Failed to get response from target application(" + resourceUrl + "). statusCode=" + statusCode + " (" + httpResponse.getStatusLine().getReasonPhrase() + ")");
    is = httpResponse.getEntity().getContent();
    BufferedInputStream bufferedInputStream = new BufferedInputStream(is);
    String errorHttpResponse = HttpConnectionUtil.readResponseData(bufferedInputStream, resourceUrl);
    throw new IntegrationException(IntegrationResMessages.INVALID_HTTP_RESPONSE.toString(), 1, statusCode, errorHttpResponse);
  }
}
catch (UnsupportedEncodingException e)
{
  Object arg1;
  HttpRoute arg0;
  HttpEntity entity;
  log.fatal("Exception when encoding request xml", e);
  throw new IntegrationException(IntegrationResMessages.ENCODE_ERROR.toString(), 1);
}
catch (IntegrationException e)
{
  throw e;
}
catch (IllegalStateException e)
{
  log.fatal("IllegalStateException when posting request", e);
  throw new IntegrationException(IntegrationResMessages.HTTP_COMMUNICATION_ERROR.toString(), 1);
}
catch (IOException e)
{
  postMethod.abort();
  log.fatal("IOException when posting request", e);
  throw new IntegrationException(IntegrationResMessages.HTTP_COMMUNICATION_ERROR.toString(), 1);
}
finally
{
  log.debug("Inside the finally method to release connections");      
  Object arg1 = null;
  HttpRoute arg0 = null;      
  this.httpClient.getConnectionManager().requestConnection(arg0, arg1);
  if (httpResponse != null)
  {
    try
    {
      HttpEntity entity = httpResponse.getEntity();
      EntityUtils.consume(entity);
    }
    catch (IOException e)
    {
      log.fatal("IOException when closing http connection:", e);
      throw new IntegrationException(IntegrationResMessages.HTTP_COMMUNICATION_ERROR.toString(), 1);
    }
  }
}   
return responseData;
}

方法executeHttpConnection

 public HttpResponse executeHTTPconnection(HttpClient httpClient, HttpRequestBase method, String destUrl)
throws IntegrationException
long t = System.currentTimeMillis();
int statusCode = -1;
String reasonPhrase = null;
HttpResponse httpResponse = null;
try
{
  httpResponse = httpClient.execute(method);
  if (httpResponse.getStatusLine() != null)
  {
    reasonPhrase = httpResponse.getStatusLine().getReasonPhrase();
    statusCode = httpResponse.getStatusLine().getStatusCode();
  }
  try
  {
    if (httpResponse != null) {
      httpResponse.getEntity().getContent();
    }
  }
  catch (IOException e)
  {
    method.abort();throw 
      new IntegrationException(IntegrationResMessages.IO_ERROR.toString(), 2);
  }
}
catch (NoHttpResponseException e)
{
  method.abort();
  throw new IntegrationException(IntegrationResMessages.DEST_SERVER_UNAVAILABLE.toString(), 2);
}
catch (SocketTimeoutException e)
{
  method.abort();
  log.error("Socket Exception when connecting rest resource, " + e.getMessage(), e);
  throw new IntegrationException(IntegrationResMessages.COMMUNICATION_TIMEOUT_ERROR.toString(), 2);
}
catch (ConnectionPoolTimeoutException e)
{
  method.abort();
  log.error("Connection manager failed to obtain a free connection from the connection pool within the timeout period, " + e.getMessage(), e);
  throw new IntegrationException(IntegrationResMessages.SYSTEM_FAILURE.toString(), 2);
}
catch (ConnectTimeoutException e)
{
  method.abort();
  log.error("Failed to establish a connection with the target server within the timeout period, " + e.getMessage(), e);
  throw new IntegrationException(IntegrationResMessages.COMMUNICATION_TIMEOUT_ERROR.toString(), 2);
}
catch (IOException e)
{
  method.abort();
  log.fatal("IOException when executing post method", e);
  throw new IntegrationException(IntegrationResMessages.IO_ERROR.toString(), 2);
}
finally
{
  try
  {
    if (httpResponse != null) {
      httpResponse.getEntity().getContent();
    }
  }
  catch (IOException e)
  {
    method.abort();
    log.error("Failed to read response.", e);
    throw new IntegrationException(IntegrationResMessages.IO_ERROR.toString(), 2);
  }
}
log.debug(destUrl + "||" + statusCode + "||" + reasonPhrase);
return httpResponse;
}

0 个答案:

没有答案