Httpclient 4.0.3 随机挂起的多个帖子
让我解释一下情况。
我有一个 servlet 将传出 GET/POST 重定向到另一个域(某种代理)上的另一个项目,其工作是处理它并返回一些内容(参数和 gif)。我使用 HttpClient 4.0.3 来执行此操作。
我的应用程序在启动时发送了多个 GET/POST,因此我设置了一次 ThreadSafeClientConnManager 来以这种方式处理多个线程。
cm_params = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(cm_params, 200);
ConnPerRouteBean connPerRoute = new ConnPerRouteBean();
HttpHost localhost = new HttpHost("localhost");
connPerRoute.setMaxForRoute(new HttpRoute(localhost), 50);
ConnManagerParams.setMaxConnectionsPerRoute(cm_params, connPerRoute);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
cm = new ThreadSafeClientConnManager(cm_params, schemeRegistry);
然后我使用这些参数创建一个新的 HttpClient,这应该足以同时处理一堆请求。当然,我对每个 GET/POST 都在 public void service() 上执行此操作,但在创建它后我使用相同的 Httpclient 对象。
httpclient = new DefaultHttpClient(cm, cm_params);
之后,我构建我的 POST 并通过执行发送它,并包含所有必需的参数和这样的三重验证。
HttpPost httpPost = new HttpPost(target+tmpString);
httpPost.setHeader("Host", request.getHeader("host"));
httpPost.setHeader("User-Agent", request.getHeader("user-agent"));
httpPost.setHeader("Accept-Encoding", request.getHeader("accept-encoding"));
httpPost.setHeader("Accept", request.getHeader("accept"));
..etc..
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(params);
urlEncodedFormEntity.setContentEncoding(HTTP.UTF_8);
httpPost.setEntity(urlEncodedFormEntity);
HttpResponse response = httpclient.execute(httpPost);
最后,我读取流并处理实体...
OutputStream os = res.getOutputStream();
InputStream is = response.getEntity().getContent();
byte[] buf = new byte[1024];
for(int n;(n=is.read(buf))!=-1;)
{
os.write(buf, 0, n);
}
// Make sure to close
is.close();
os.close();
// Flush entities just in case
EntityUtils.consume(urlEncodedFormEntity);
EntityUtils.consume(response.getEntity());
urlEncodedFormEntity.getContent().close();
response.getEntity().getContent().close();
所以我的问题是,当我加载页面时,代码运行得很好。已正确处理 4 个发送的请求(1 个 GET、3 个 POST)。基本上返回一些参数和 1 个我在页面上打印的小 gif。
但是,一旦我开始对我的应用程序进行压力测试,IE 在 4-5 个选项卡中加载同一页面,每当我同时执行多个 POST 时,我的应用程序似乎都会随机挂起。我认为即使我使用相同的 Httpclient 对象,我也不会有任何问题,因为我正确声明了 ThreadSafeClientConnManager (我认为?),所以它应该处理多个线程。
有人知道我做错了什么吗?如果我一一加载我的选项卡,它不会挂起。就在我同时刷新多个选项卡时。
有人知道吗? :S(抱歉英语不是我的母语^^;)
let me explain the situation.
I have a servlet redirecting outgoing GET/POST to another project on another domain (some kind of proxy) whose job is to handle it and return some stuff (params and a gif). Im using HttpClient 4.0.3 to do this.
There are multiple GET/POST sent by my app on startup, so I setup once a ThreadSafeClientConnManager to handle multiple threads this way.
cm_params = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(cm_params, 200);
ConnPerRouteBean connPerRoute = new ConnPerRouteBean();
HttpHost localhost = new HttpHost("localhost");
connPerRoute.setMaxForRoute(new HttpRoute(localhost), 50);
ConnManagerParams.setMaxConnectionsPerRoute(cm_params, connPerRoute);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
cm = new ThreadSafeClientConnManager(cm_params, schemeRegistry);
Then I create a new HttpClient with those params, which should be enough to handle a bunch of request at the same time. Of course, I do this on public void service() for every GET/POST but I use the same Httpclient object after I created it.
httpclient = new DefaultHttpClient(cm, cm_params);
After that I build up my POST and send it via execute, with all the requiered params and such triple verified.
HttpPost httpPost = new HttpPost(target+tmpString);
httpPost.setHeader("Host", request.getHeader("host"));
httpPost.setHeader("User-Agent", request.getHeader("user-agent"));
httpPost.setHeader("Accept-Encoding", request.getHeader("accept-encoding"));
httpPost.setHeader("Accept", request.getHeader("accept"));
..etc..
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(params);
urlEncodedFormEntity.setContentEncoding(HTTP.UTF_8);
httpPost.setEntity(urlEncodedFormEntity);
HttpResponse response = httpclient.execute(httpPost);
Finally I read the stream and handle the entities...
OutputStream os = res.getOutputStream();
InputStream is = response.getEntity().getContent();
byte[] buf = new byte[1024];
for(int n;(n=is.read(buf))!=-1;)
{
os.write(buf, 0, n);
}
// Make sure to close
is.close();
os.close();
// Flush entities just in case
EntityUtils.consume(urlEncodedFormEntity);
EntityUtils.consume(response.getEntity());
urlEncodedFormEntity.getContent().close();
response.getEntity().getContent().close();
So my problem is, the code is working perfectly well when I load my page. There are 4 request sent (1 GET, 3 POST) correctly handled. Basicly returning some params and 1 small gif that I print on my page.
But as soon I start to Stress Test my app, I.E. loading the same page in 4-5 tabs, my app seems to hang randomly whenever I execute multiple POST at the same time. I thought I wouldn't have any problem even if I use the same Httpclient object since I declared my ThreadSafeClientConnManager correctly (I think?) so it should handle multiple thread.
Anyone know what I am doing wrong? If I load my tabs 1 by 1, it doesnt hang. Just when I refresh more than 1 tab at the same time.
Anyone have a clue? :S (sry english isnt my first language ^^;)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我陷入了同样的错误。我们注意到 HttpClient 不会自行关闭。
我所做的是,我在未清除的 HttpClient 和 HttpResponse 上尝试了 HttpClientUtils.closeQuietly() 方法。它帮助了我的事业,并且它不再挂起。您也可以尝试和试验它。
I got stuck into the same error. What we noticed was that HttpClient doesn't close itself.
What I did was, I tried HttpClientUtils.closeQuietly() method on my uncleared HttpClient and HttpResponse.It helped my cause, and it stopped hanging anymore. You can also try and experiment with it.
@Apache Fan,设置这个:
ConnManagerParams.setMaxTotalConnections(cm_params, 200);
connPerRoute.setDefaultMaxPerRoute(50);
怀疑我可能会耗尽连接,我打开 3-4 个选项卡,它就耗尽了...每个选项卡可能有 4 个 POST,所以不会加起来:S
@Apache Fan, setting this :
ConnManagerParams.setMaxTotalConnections(cm_params, 200);
connPerRoute.setDefaultMaxPerRoute(50);
Doubt I can run out of connection, I open 3-4 tab and it runs out... theres maybe 4 POST per tab so that doesnt add up :S
您可能想从 HttpClient API -
也许您的应用程序耗尽了池连接,您需要增加池大小。
You may want to take a look at this from the HttpClient API -
Maybe your application is running out of pooled connection and you need to increase the pool size.
最近我试图实现这一点,但我遇到了一些新问题,例如当我第一次发送请求时,它在没有cookie的情况下发送,但在第二次httpContext自动添加cookie
但这是标准的发送方式,但有时您请求的服务器会在没有cookie的情况下接受,因此我使用了INTERCEPTOR。第二次它会删除自动添加的 cookie,之后它工作正常,请使用此
httpClient
拦截器,使用下面的代码:Recently i was trying to achieve this but i got some new problem like when first time i was sending request then it was sending without cookie but in second time httpContext was adding cookie automatically
but this is the standard way to send but sometimes your requested server accept without cookie so for that i have used INTERCEPTOR. In second time it removes that auto added cookies after that it was working fine please use this
httpClient
interceptor use below code :