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

实现HTTP连接池的正确方法

叶衡虑
2023-03-14

我使用Apache HTTP客户端在我的REST API调用到某些Web服务的连池。

奇怪的是,尽管我使用了HTTP连接池,但我的性能并没有任何提高。

我正在使用Apache HTTP客户端连接到我的web服务,其中的代码如下所示:

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();

cm.setMaxTotal(200);

cm.setDefaultMaxPerRoute(20);

HttpHost host = new HttpHost("abc.com", 80);
cm.setMaxPerRoute(new HttpRoute(host), 50);

CloseableHttpClient httpClient = HttpClients.custom()
        .setConnectionManager(cm)
        .build();

我使用Spring的RestTemplate来包装使用Spring的HttpComponents客户端HttpRequestFactory实现Apache的HttpClient

但是即使我不使用连池,即使用Spring的SimpleClientHttp刚需工厂,我也没有性能优势。

我的连接仍然需要相同的时间才能完成。

我所做的是实现HTTP连接池的正确方法吗?我做错什么了吗?

请让我知道,如果任何进一步的信息需要从我这边。


共有3个答案

毛勇
2023-03-14

你的配置似乎是正确的。您可以使用多线程来使用系统的资源来获得性能。

    HttpGet get = new HttpGet("http://www.codersjargon.com");

    PoolingHttpClientConnectionManager connManager 
      = new PoolingHttpClientConnectionManager();

    CloseableHttpClient client = HttpClients.custom().
        setConnectionManager(connManager).build();

     MultiHttpClientConnThread thread1 = new MultiHttpClientConnThread(client, get);
     MultiHttpClientConnThread thread2 = new MultiHttpClientConnThread(client, get);
     MultiHttpClientConnThread thread3 = new MultiHttpClientConnThread(client, get); 
     thread1.start();
     thread2.start();
     thread3.start(); 
     thread1.join(); 
     thread2.join();
     thread3.join();
万俟均
2023-03-14

我相信您正在正确设置HttpClient和池管理器。

我的实现与使用HttpClients有一点不同。custom(),我正在使用HttpClientBuilder。create(),但随后具有与您相同的方法调用。根据另一个堆栈溢出的答案,这不会有什么区别。

我以前在Spring应用程序中使用过这种配置,并且有很好的好处。我想知道反应是否发生得足够快,以至于你没有看到很大的好处?我唯一能想到的另一件事是,如果可能的RestTem板没有正确配置。

齐向笛
2023-03-14

请注意HTTPhtml" target="_blank">客户端池的工作方式,它可能会在短时间内提高性能。检查以下分析:

来自PoollightTPClientConnectionManager javadocs

在版本4.4中更改了对过时连接的处理。以前,代码会在重新使用之前默认检查每个连接。代码现在仅在上次使用连接后的时间超过已设置的超时时才检查连接。默认超时设置为2000ms

从池性能的角度来看,这意味着,只要管理器在默认情况下认为某个特定路由在2秒钟内处于“活动”状态,就可以重用该路由的连接
在2秒钟的非活动状态后,到该路由的连接将被视为过时并被丢弃,因此在下次请求该路由时将导致连接初始化惩罚。

换句话说,开箱即用,池在2秒内提高了第一个连接之后的性能。重型航线受益最大。

作为一个简单的测试,将池大小设置为一个小值,如最大5。在linux上发送5个请求并检查到该路由的已建立连接数

watch"netstat-ant|grep

您应该看到5个连接。等待10或20秒,然后向同一路由发送2个请求,您应该看到这5个连接已关闭,2个新连接已创建。通过调试日志记录也可以观察到这一点。这里有一篇好文章作为参考
http日志上的Apache官方文档。

 类似资料:
  • 我们在我们的项目中使用连接池。我们在我们的项目中看到,在连接关闭后,语句也会关闭。我知道在连接池的情况下,连接关闭后,到数据库的物理连接不会关闭,而是返回到池进行重用。所以我的问题是: 如果在连接关闭后关闭语句会发生什么?语句是否会正确关闭/关闭连接是否会关闭所有语句,关闭语句是多余的/语句是打开的,尽管连接返回到池中,但由于打开语句,它是不可重用的?(我们同时使用Statement和Prepar

  • 我正在使用HikariDataSource连接到MariaDB数据库。以下类返回一个。 这是执行select查询的方法。该类还包含一个close方法 try with块自动关闭对象,但如何关闭连接池?例如,我应该在数据库操作之后调用close方法吗 当我不调用方法时,我看不到任何关于关机启动的控制台输出。这是关闭和连接池的正确方法吗?

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

  • 我正在实现一个连接池(JDBC连接和SMPP连接)。我知道有几个经过良好测试的连接池。但我只想自己实现。我在多线程环境中使用它。这更是我个人的兴趣所在。我的实现是这样的。我创建一个ConcurrentLinkedQueue并将连接推送到队列。每次线程请求连接时,都会从队列中弹出连接。作业完成后,线程将连接推回到队列。我的连接轮询实现类如下所示。 我只想知道这个实现有什么问题。请指教。我想为JDBC

  • 本文向大家介绍自定义一个简单的JDBC连接池实现方法,包括了自定义一个简单的JDBC连接池实现方法的使用技巧和注意事项,需要的朋友参考一下 一、什么是JDBC连接池? 在传统的JDBC连接中,每次获得一个Connection连接都需要加载通过一些繁杂的代码去获取,例如以下代码: 这样繁杂的操作只为了获取一次连接,当然,我们可以将其封装成一个工具类来访问(上图以封装好Connection的连接),但

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