当前位置: 首页 > 知识库问答 >
问题:

Http客户端4.5不重用相同的连接使用池连接管理器在java

单于扬
2023-03-14

下面的代码使用的是ApacheHTTP客户端4.5版本的池连接管理器。如果我发出50个请求,我会在netstat中看到50个不同的tcp端口被使用,但在任何时候都最多使用5个连接。我在wire shark中也看到了filtertcp。旗帜。syn==1

我的代码:

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.glassfish.jersey.SslConfigurator;
import org.json.JSONException;
import org.json.JSONObject;

public class App3Conn {
    private static CloseableHttpClient client;


    static String target="https://example.com";

    static PoolingHttpClientConnectionManager cm ;
static{

SslConfigurator sslConfig = SslConfigurator.newInstance()
            .securityProtocol("TLS")
            .keyStoreFile("/Users/file")
            .keyStorePassword("passw")
            .keyStoreType("JKS")
            .trustStoreFile("/Users/file");

    SSLContext sslCtx = sslConfig.createSSLContext();
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslCtx,NoopHostnameVerifier.INSTANCE);
    Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.getSocketFactory())
            .register("https", sslsf)
            .build();


    cm = new PoolingHttpClientConnectionManager(r);
    cm.setMaxTotal(15);
    cm.setDefaultMaxPerRoute(5);

    client = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm).build();


}
public static void main(String a[]) throws JSONException, ClientProtocolException, IOException
{

    JSONObject jsonMessage = new JSONObject();



    JSONObject jsonResponse;

    jsonMessage.put("keyID", "keyID" );


     StringEntity se = new StringEntity(jsonMessage.toString());
     CloseableHttpResponse response2;
    HttpPost httpPost = new HttpPost(target);
    httpPost.setEntity(se);
    httpPost.setHeader("Accept", "application/json");
    httpPost.setHeader("Content-type", "application/json");
    httpPost.setHeader("Connection", "keep-alive");
    int i;
    for(i=0;i<50;i++)
    {

        response2 = client.execute(httpPost);


     HttpEntity entity2 = response2.getEntity();
     String result = EntityUtils.toString(entity2);

     EntityUtils.consume(entity2);


     jsonResponse = new JSONObject(result);

    String text = jsonResponse.getString("result");


    response2.close();
    }
}
}

共有2个答案

谢承
2023-03-14

如果要重用池连接,请不要关闭响应。不需要回答。close();回答close()关闭所有输入/输出资源,最后关闭tcp连接(套接字)。

国胤
2023-03-14

我以前见过这个。这取决于Apache连接池的工作方式。不透明的状态成员与池条目关联,并且在请求(租用)池条目时必须与请求的状态匹配。

尝试连接租用时,请求的状态为null。然而,当连接被放回池中时,状态被设置为SSL对等方的X500主体对象。这发生在DefaultUserTokenHandler类中。幸运的是,当我们创建HttpClient类时,这是可以重写的。下面是一个例子:

HttpClient apacheHttpClient = HttpClients.custom()
    .setConnectionReuseStrategy(new DefaultConnectionReuseStrategy())
    .setConnectionManager(new PoolingHttpClientConnectionManager(r))
    .setUserTokenHandler(new UserTokenHandler() {
      @Override
      public Object getUserToken(HttpContext context) {
        return null;
      }
    })
    .build();

请检查您没有丢失您依赖于DefaultUserTokenHandler的任何东西,如果您创建的HttpClient可以通过相同的HTTP路由连接到多个SSL对等体,则不要使用此方法。在我的情况下,此客户端用于连接到单个SSL服务器

 类似资料:
  • 我试图理解netty http客户端连接池。如果是NIO和异步的,那么这个连接池的意义是什么? 例如:如果服务A调用服务B,并且服务A的客户端连接池计数设置为50,那么这是否意味着我们最多只能发出50个并行请求? 更新: 我在3.5秒内完成了所有通话。理想情况下,有一个连接,我应该在150秒内完成。

  • 出身背景 我需要连接到不同客户端的服务器。 每个客户端连接应该使用唯一的TLS证书。 服务器上的MTLS已就位。 我想使用连池来提高延迟。 使用以下超文本传输协议客户端 我的假设当管理连接池中的连接时,当选择连接时,在选择连接池中的相同连接之前应该考虑客户端证书。我不希望连接为clientA使用clientB TLS证书,反之亦然。 问题是这个假设是真的吗? 情景1) 我将每条路线的最大连接数设置

  • 执行kafka客户端的生产者/消费者连接池有意义吗? kafka是否在内部维护已初始化并准备好使用的连接对象列表? 我们希望最小化连接创建的时间,这样在发送/接收消息时就不会有额外的开销。 目前,我们正在使用apache共享池库来保持连接。 任何帮助都将不胜感激。

  • 我们正在用Java重写来自PHP的web应用程序。我认为,但我不是很确定,我们可能会在连接池方面遇到问题。应用程序本身是多租户的,是“独立数据库”和“独立模式”的组合。 对于每个Postgres数据库服务器实例,可以有一个以上的数据库(命名为schemax_XXX),其中包含一个以上的模式(模式是租户)。注册时,可能会发生以下两种情况之一: 在编号最高的schema_XXX数据库中创建新的租户模式

  • 问题内容: 我正在设计一个将Redis用作数据库的Web服务,并且我想了解使用Redis与StackService客户端连接的最佳实践。 关键是我一直在阅读有关Redis的文章,发现与服务器交互的最佳方法是使用单个并发连接。 问题是,尽管每当Web客户端向Web服务发出请求时,我都会使用 PooledRedisClientManager ,但我又获得了一个到Redis服务器的连接客户端(打开的连接

  • 问题内容: 如何使用HttpClient创建连接池? 我必须经常连接同一台服务器。值得建立这样一个游泳池吗? 是否可以保持实时连接并将其用于各种请求,如果可以,我该如何做? 我正在使用Apache HTTP Client在Java中进行开发。 问题答案: [假设Java和Apache的HttpClient] 使用ThreadSafeClientConnManager。将单个全局实例传递给每个Htt