【问题标题】:Connection Eviction strategy in Http Connection Pooling in JavaJava中Http连接池中的连接驱逐策略
【发布时间】:2017-07-15 07:19:15
【问题描述】:

我正在尝试在 java 中为 Web 服务实现 http 连接池。该服务会收到一个请求,然后调用其他http服务。

public final class HttpClientPool {
 private static HttpClientPool instance = null;
 private PoolingHttpClientConnectionManager manager;
 private IdleConnectionMonitorThread monitorThread;
 private final CloseableHttpClient client;

 public static HttpClientPool getInstance() {
  if (instance == null) {
   synchronized(HttpClientPool.class) {
    if (instance == null) {
     instance = new HttpClientPool();
    }
   }
  }
  return instance;
 }

 private HttpClientPool() {
  manager = new PoolingHttpClientConnectionManager();
  client = HttpClients.custom().setConnectionManager(manager).build();
  monitorThread = new IdleConnectionMonitorThread(manager);
  monitorThread.setDaemon(true);
  monitorThread.start();
 }

 public CloseableHttpClient getClient() {
  return client;
 }
}


class IdleConnectionMonitorThread extends Thread {
 private final HttpClientConnectionManager connMgr;
 private volatile boolean shutdown;

 IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {
  super();
  this.connMgr = connMgr;
 }

 @Override
 public void run() {
  try {
   while (!shutdown) {
    synchronized(this) {
     wait(5000);
     // Close expired connections
     connMgr.closeExpiredConnections();
     // Optionally, close connections
     // that have been idle longer than 30 sec
     connMgr.closeIdleConnections(60, TimeUnit.SECONDS);
    }
   }
  } catch (InterruptedException ex) {
   //
  }
 }

 void shutdown() {
  shutdown = true;
  synchronized(this) {
   notifyAll();
  }
 }
}
  1. 正如Connection Management 文档中提到的连接驱逐策略而不是使用IdleConnectionMonitorThread 如果我使用manager.setValidateAfterInactivity 会怎样。以上两种方式的优缺点是什么?

  2. 上面的Http连接池实现是否正确?

【问题讨论】:

    标签: java connection-pooling apache-httpclient-4.x


    【解决方案1】:

    #setValidateAfterInactivity 设置为正值时,持久连接将在租用请求时得到验证。也就是说,在尝试重用它们之前,不会自动从池中逐出陈旧和不可重用的连接。

    运行一个专用线程,该线程以指定的时间间隔迭代持久连接并从池中删除过期或空闲连接,以确保主动连接驱逐,但代价是额外线程和稍高的池锁争用。

    【讨论】:

    • 在我的问题hc.apache.org/httpcomponents-client-ga/tutorial/html/… 中发布的链接中。提到了The stale connection check is not 100% reliable. The only feasible solution that does not involve a one thread per socket model for idle connections is a dedicated monitor thread。那么这对setValidateAfterInactivity 也成立吗?
    • 是的,确实如此。鉴于过时的连接检查相对昂贵,从 4.4 版开始,HttpClient 不再检查每个连接,而只检查那些在一段时间内处于非活动状态的连接
    • 如果我正确设置setValidateAfterInactivity 将运行陈旧检查连接是否空闲了setValidateAfterInactivity 中指定的那么多毫秒,即使那样它也不可靠。如果我们想要完全的可靠性,那么我们应该使用IdleMonitorThread 方法吗?
    • HTTP 协议没有完全的可靠性,因为 HTTP 在设计上没有交付保证。必须始终准备好在失败的情况下重试/重新执行请求(前提是这些请求被认为是安全的)。连接验证/驱逐仅有助于减少重试次数
    • 是的。您能否解释一下第一条评论中发布的The only feasible solution that does not involve a one thread per socket model for idle connections is a dedicated monitor thread 的声明是什么意思?
    【解决方案2】:

    在 HttpClient 4.5.3 中,manager.setValidateAfterInactivity 的默认值为 2000,即 2 秒。所以我建议不要使用IdleConnectionMonitorThread,除非您希望应用程序同时验证非活动连接并进行清理。

    【讨论】:

      猜你喜欢
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      相关资源
      最近更新 更多