代码之家  ›  专栏  ›  技术社区  ›  CharlieShi

Httpclient引发等待池连接超时异常

  •  1
  • CharlieShi  · 技术社区  · 7 年前

    现在,我正在为我们的上传图像服务处理一个例外,场景如下:

    我们有一个网页,来自世界各地的用户可以上传他们的图像到我们的服务器,图像通常保持在3MB左右。现在我们举行了一次促销活动,因此上传到我们服务器上的图像数量非常大,但这导致服务器抛出异常“org.apache.http.conn.ConnectionPoolTimeoutException:Timeout等待来自池的连接”。

    我们使用apache httpclient作为核心上传中间件,其版本为4.5。*,我们使用上述方法正确处理了响应 in this article . 代码如下:

     if (returnType != StorageHttpResponse.class && response != null) {
            EntityUtils.consumeQuietly(response.getEntity());
            httpRequest.abort();
        }
    

    因此,在这里,我通过在finally代码块中使用响应实体来正确处理它,但我仍然无法阻止服务抛出连接池超时异常。

    我还需要在服务中添加其他内容吗?我真的使用redis来排队等待用户的上传请求和后期处理吗?

    此处的完整代码:

     public <T> T excute(Request request, Class<T> returnType) {
        Preconditions.checkState(!isShutDown, "JSSHttpClient is destory!");
        HttpRequestBase httpRequest = new HttpRequestBuild(this.credential).build(request);
        HttpResponse response = null;
        try {
            response = this.client.execute(httpRequest);
            if (errorHandler.hasError(request, response)) {
                int statusCode = response.getStatusLine().getStatusCode();
                log.warn("Unexpected response," + request + " http code [" + statusCode + "]");
                errorHandler.handleError(response);
            }
            if (returnType != null && returnType != StorageHttpResponse.class) {
                return JsonMessageConverter.read(returnType, response);
            }
            if (returnType == StorageHttpResponse.class) {
                return (T) new StorageHttpResponse(response);
            }
        } catch (IOException e) {
            Throwables.propagate(e);
        } finally {
            if (returnType != StorageHttpResponse.class && response != null) {
                EntityUtils.consumeQuietly(response.getEntity());
                httpRequest.abort();
            }
        }
        return null;
    }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Manoharan    4 年前

    您可以在属性或yml文件中设置参数,如下所示。

    http: 池: 尺寸:100 插座超时:20000 默认MaxPerRoute:200 最大路径: - 主机:本地主机 端口:8080 maxPerRoute:100 - 方案:https 主机:{{URL}} 端口:-1 maxPerRoute:200

        2
  •  1
  •   CharlieShi    7 年前

    最后,我们解决了这个问题,而不是使用代码。因为我们都知道,如果不直接使用响应,则不会释放请求的连接。所以在我们的代码中,我们通常首先使用响应。

    我们并不是通过使用更好的代码来解决这个问题,而是根据我们的业务场景稍微修改了一些参数,如maxconnectionpoolsize、maxconnectionperroute和maxconnectiontimeout。然后运行它,现在一切似乎都好了。希望这对你有帮助。