现在正在处理我们的上传图像服务的例外情况,以下场景:
我们有一个网页,来自世界各地的用户可以将他们的图像上传到我们的服务器,图像通常保持在3MB左右。现在我们举办促销活动,因此上传到我们服务器的图像数量非常巨大,但这导致服务器抛出异常“org.apache.http.conn.ConnectionPoolTimeoutException:等待池连接超时”。
我们使用apache httpclient作为核心上传中间件,其版本为4.5.*,我们使用本文中提到的方法正确处理了响应。 代码如下:
if (returnType != StorageHttpResponse.class && response != null) {
EntityUtils.consumeQuietly(response.getEntity());
httpRequest.abort();
}
此外,服务的最大连接池为 128,最大连接超时为 50000 毫秒。我们使用流模式上传图片,而不是直接上传图片文件。
所以在这里,我通过在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;
}
http:
pool:
size: 100
sockettimeout: 20000
defaultMaxPerRoute: 200
maxPerRoutes:
-
scheme: http
host: localhost
port: 8080
maxPerRoute: 100
-
scheme: https
host: {{URL}}
port: -1
maxPerRoute: 200
我们不是通过使用更好的代码来解决这个问题,而是根据我们的业务场景稍微修改了一些参数,如 maxconnectionpoolsize、maxconnectionperroute 和 maxconnectiontimeout。然后运行它,现在一切似乎都正常了。希望这对您有帮助。