Java 中的 Http 连接池中的连接逐出策略

Connection Eviction strategy in Http Connection Pooling in Java

我正在尝试在 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连接池实现是否正确?

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

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

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