2017-02-24 96 views
0

我正在尝试在java中为web服务实现http连接池。该服务将收到一个请求,然后调用其他http服务。Java中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连接池实现是否正确?

回答

1

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

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

+0

在我发布在我的问题https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d5e418的链接中。它被提及'陈旧的连接检查不是100%可靠的。每个套接字模型不包含一个用于空闲连接的线程的唯一可行解决方案是专用监视器线程。那么这也适用于'setValidateAfterInactivity'吗? – tuk

+0

是的,它的确如此。鉴于过时的连接检查相对昂贵HttpClient从4.4版开始不再检查每个连接,而只检查那些在一段时间内处于非活动状态的连接 – oleg

+0

如果我正确设置'setValidateAfterInactivity',将运行过期检查如果连接在'setValidateAfterInactivity'中指定的那么多毫秒,即使它不是可靠的。如果我们想要完全可靠,那么我们应该使用'IdleMonitorThread'方法? – tuk