2

我们有一个 HttpClient(apache.DefaultHttpClient) 对象的池(GenericObjectPool)。HttpPost 对象通过这些客户端执行,可能同时发送 Post 请求。使用的协议是:HTTP/1.1 with keepalive。

在通过 netstat 进行负载测试期间观察到,新套接字连接被不加选择地创建,旧连接进入 TIME_WAIT。


日志摘录:-

[Worker-2] org.apache.http.impl.conn.Wire 63 - >> "POST /INBOX/4504a09e-13c0-3853-a285-9e2b9a22f65e/1e1e5a20-a8c1-11e2-99b8-7c19e9129271 HTTP/1.1[\r][\n]"

[Worker-2] org.apache.http.impl.conn.Wire 63 - >> "Content-Type: application/json; charset=UTF-8[\r][\n]"

[Worker-2] org.apache.http.impl.conn.Wire 63 - >> "Content-Length: 117[\r][\n]"

[Worker-2] org.apache.http.impl.conn.Wire 63 - >> "Host: rwcdtgxb0402:15010[\r][\n]"

[Worker-2] org.apache.http.impl.conn.Wire 63 - >> "Connection: Keep-Alive[\r][\n]"

[Worker-2] org.apache.http.impl.conn.Wire 63 - >> "User-Agent: Apache-HttpClient/4.2.1 (java 1.5)[\r][\n]"

[Worker-2] org.apache.http.impl.conn.Wire 63 - >> "[\r][\n]"

[Worker-2] org.apache.http.impl.conn.Wire 63 - << "HTTP/1.1 200 OK[\r][\n]"

[Worker-2] org.apache.http.impl.conn.Wire 63 - << "Content-Length: 0[\r][\n]"

[Worker-2] org.apache.http.impl.conn.Wire 63 - << "[\r][\n]"

[Worker-2] org.apache.http.impl.conn.DefaultClientConnection 254 - Receiving response: HTTP/1.1 200 OK

[Worker-2] org.apache.http.impl.conn.DefaultClientConnection 257 - << HTTP/1.1 200 OK

[Worker-2] org.apache.http.impl.conn.DefaultClientConnection 260 - << Content-Length: 0

[Worker-2] org.apache.http.impl.client.DefaultRequestDirector 540 - Connection can be kept alive indefinitely

**[Worker-2] org.apache.http.impl.conn.DefaultClientConnection 154 - Connection 0.0.0.0:51211<->192.168.88.172:15010 shut down**

[Worker-2] org.apache.http.impl.conn.BasicClientConnectionManager 189 - Releasing connection org.apache.http.impl.conn.ManagedClientConnectionImpl@12f65ce5

DefaultClientConnection.shutdown (Connection 0.0.0.0:51210<->192.168.88.172:15010 关闭) 从客户端关闭连接吗?它是如何被调用的?在从服务器 httpPost.releaseConnection() 收到响应 (200OK) 后的代码中,仅在客户端代码中执行。

我应该怎么做才能将连接保持在 ESTABLISHED 状态并重用它们,而不是为每个请求创建连接并且它们进入 TIME_WAIT。

任何帮助将不胜感激。谢谢你。

4

2 回答 2

1

注意调用EntityUtils.console(entity)做得更多,应该使用:

    /**
     * Ensures that the entity content is fully consumed and 
     * the content stream, if exists, is closed.
     *
     * @param entity the entity to consume.
     * @throws IOException if an error occurs reading the input stream
     *
     * @since 4.1
     */
    public static void consume(final HttpEntity entity) throws IOException {
        if (entity == null) {
            return;
        }
        if (entity.isStreaming()) {
            final InputStream inStream = entity.getContent();
            if (inStream != null) {
                inStream.close();
            }
        }
    }
于 2020-08-13T13:28:49.390 回答
0

几天前解决了问题。

错误:在 HttpClient 对象上调用 releaseConnection()。但是,避免它也没有解决问题。

更正:为保持连接活动(处于 ESTABLISHED 状态)而采取的操作是通过以下示例代码:

HttpClient client = new org.apache.http.impl.client.DefaultHttpClient();
...
org.apache.http.HttpResponse response = client.executed(HttpPost) ;
org.apache.http.HttpEntity en = response.getEntity();
if (en != null) {
  en.getContent().close();
}

一旦收到 HttpResponse,为了重用和维护创建的连接,只需关闭 http-response 上的 InputStream (en.getContent())。不要在 HttpPost 或 Client 对象上调用任何其他释放方法。

使用 JMeter 负载测试此处理并发现它有效。还没有观察到任何副作用!

于 2013-05-07T07:09:10.487 回答