httpclient evict操作源碼解讀
序
本文主要研究一下httpclient的evict操作
evictExpiredConnections
org/apache/http/impl/client/HttpClientBuilder.java
public class HttpClientBuilder {
private boolean evictExpiredConnections;
/**
* Makes this instance of HttpClient proactively evict expired connections from the
* connection pool using a background thread.
* <p>
* One MUST explicitly close HttpClient with {@link CloseableHttpClient#close()} in order
* to stop and release the background thread.
* <p>
* Please note this method has no effect if the instance of HttpClient is configuted to
* use a shared connection manager.
* <p>
* Please note this method may not be used when the instance of HttpClient is created
* inside an EJB container.
*
* @see #setConnectionManagerShared(boolean)
* @see org.apache.http.conn.HttpClientConnectionManager#closeExpiredConnections()
*
* @since 4.4
*/
public final HttpClientBuilder evictExpiredConnections() {
evictExpiredConnections = true;
return this;
}
}HttpClientBuilder提供了evictExpiredConnections方法,該方法會設置evictExpiredConnections為true
evictIdleConnections
public class HttpClientBuilder {
private boolean evictIdleConnections;
private long maxIdleTime;
private TimeUnit maxIdleTimeUnit;
/**
* Makes this instance of HttpClient proactively evict idle connections from the
* connection pool using a background thread.
* <p>
* One MUST explicitly close HttpClient with {@link CloseableHttpClient#close()} in order
* to stop and release the background thread.
* <p>
* Please note this method has no effect if the instance of HttpClient is configuted to
* use a shared connection manager.
* <p>
* Please note this method may not be used when the instance of HttpClient is created
* inside an EJB container.
*
* @see #setConnectionManagerShared(boolean)
* @see org.apache.http.conn.HttpClientConnectionManager#closeExpiredConnections()
*
* @param maxIdleTime maximum time persistent connections can stay idle while kept alive
* in the connection pool. Connections whose inactivity period exceeds this value will
* get closed and evicted from the pool.
* @param maxIdleTimeUnit time unit for the above parameter.
*
* @since 4.4
*/
public final HttpClientBuilder evictIdleConnections(final long maxIdleTime, final TimeUnit maxIdleTimeUnit) {
this.evictIdleConnections = true;
this.maxIdleTime = maxIdleTime;
this.maxIdleTimeUnit = maxIdleTimeUnit;
return this;
}
}HttpClientBuilder提供了evictIdleConnections方法,該方法會設置evictIdleConnections為true,同時設置maxIdleTime及maxIdleTimeUnit
build
if (!this.connManagerShared) {
if (closeablesCopy == null) {
closeablesCopy = new ArrayList<Closeable>(1);
}
final HttpClientConnectionManager cm = connManagerCopy;
if (evictExpiredConnections || evictIdleConnections) {
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor(cm,
maxIdleTime > 0 ? maxIdleTime : 10, maxIdleTimeUnit != null ? maxIdleTimeUnit : TimeUnit.SECONDS,
maxIdleTime, maxIdleTimeUnit);
closeablesCopy.add(new Closeable() {
@Override
public void close() throws IOException {
connectionEvictor.shutdown();
try {
connectionEvictor.awaitTermination(1L, TimeUnit.SECONDS);
} catch (final InterruptedException interrupted) {
Thread.currentThread().interrupt();
}
}
});
connectionEvictor.start();
}
closeablesCopy.add(new Closeable() {
@Override
public void close() throws IOException {
cm.shutdown();
}
});
}HttpClientBuilder的build方法會在connManagerShared為false的前提下判斷是否開啟evictExpiredConnections或者evictIdleConnections,是則創(chuàng)建IdleConnectionEvictor,往closeablesCopy注冊shutdown及awaitTermination,最后執(zhí)行connectionEvictor.start()。如果只是設置了evictExpiredConnections,則默認sleepTime為10s,否則sleepTime及maxIdleTime都為設置的值(>0)
IdleConnectionEvictor
org/apache/http/impl/client/IdleConnectionEvictor.java
/**
* This class maintains a background thread to enforce an eviction policy for expired / idle
* persistent connections kept alive in the connection pool.
*
* @since 4.4
*/
public final class IdleConnectionEvictor {
private final HttpClientConnectionManager connectionManager;
private final ThreadFactory threadFactory;
private final Thread thread;
private final long sleepTimeMs;
private final long maxIdleTimeMs;
private volatile Exception exception;
public IdleConnectionEvictor(
final HttpClientConnectionManager connectionManager,
final ThreadFactory threadFactory,
final long sleepTime, final TimeUnit sleepTimeUnit,
final long maxIdleTime, final TimeUnit maxIdleTimeUnit) {
this.connectionManager = Args.notNull(connectionManager, "Connection manager");
this.threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory();
this.sleepTimeMs = sleepTimeUnit != null ? sleepTimeUnit.toMillis(sleepTime) : sleepTime;
this.maxIdleTimeMs = maxIdleTimeUnit != null ? maxIdleTimeUnit.toMillis(maxIdleTime) : maxIdleTime;
this.thread = this.threadFactory.newThread(new Runnable() {
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(sleepTimeMs);
connectionManager.closeExpiredConnections();
if (maxIdleTimeMs > 0) {
connectionManager.closeIdleConnections(maxIdleTimeMs, TimeUnit.MILLISECONDS);
}
}
} catch (final Exception ex) {
exception = ex;
}
}
});
}
public IdleConnectionEvictor(
final HttpClientConnectionManager connectionManager,
final long sleepTime, final TimeUnit sleepTimeUnit,
final long maxIdleTime, final TimeUnit maxIdleTimeUnit) {
this(connectionManager, null, sleepTime, sleepTimeUnit, maxIdleTime, maxIdleTimeUnit);
}
public IdleConnectionEvictor(
final HttpClientConnectionManager connectionManager,
final long maxIdleTime, final TimeUnit maxIdleTimeUnit) {
this(connectionManager, null,
maxIdleTime > 0 ? maxIdleTime : 5, maxIdleTimeUnit != null ? maxIdleTimeUnit : TimeUnit.SECONDS,
maxIdleTime, maxIdleTimeUnit);
}
public void start() {
thread.start();
}
public void shutdown() {
thread.interrupt();
}
public boolean isRunning() {
return thread.isAlive();
}
public void awaitTermination(final long time, final TimeUnit timeUnit) throws InterruptedException {
thread.join((timeUnit != null ? timeUnit : TimeUnit.MILLISECONDS).toMillis(time));
}
static class DefaultThreadFactory implements ThreadFactory {
@Override
public Thread newThread(final Runnable r) {
final Thread t = new Thread(r, "Connection evictor");
t.setDaemon(true);
return t;
}
};
}IdleConnectionEvictor創(chuàng)建了一個thread,使用while循環(huán),每次循環(huán)sleep指定的sleepTimeMs時間,然后執(zhí)行connectionManager.closeExpiredConnections();對于maxIdleTimeMs大于0的,執(zhí)行connectionManager.closeIdleConnections(maxIdleTimeMs, TimeUnit.MILLISECONDS)
closeExpired
org/apache/http/pool/AbstractConnPool.java
/**
* Closes expired connections and evicts them from the pool.
*/
public void closeExpired() {
final long now = System.currentTimeMillis();
enumAvailable(new PoolEntryCallback<T, C>() {
@Override
public void process(final PoolEntry<T, C> entry) {
if (entry.isExpired(now)) {
entry.close();
}
}
});
}closeExpired主要是遍歷available,挨個判斷是否expired(取決于connTimeToLive值),是則執(zhí)行close
closeIdle
org/apache/http/pool/AbstractConnPool.java
/**
* Closes connections that have been idle longer than the given period
* of time and evicts them from the pool.
*
* @param idletime maximum idle time.
* @param timeUnit time unit.
*/
public void closeIdle(final long idletime, final TimeUnit timeUnit) {
Args.notNull(timeUnit, "Time unit");
long time = timeUnit.toMillis(idletime);
if (time < 0) {
time = 0;
}
final long deadline = System.currentTimeMillis() - time;
enumAvailable(new PoolEntryCallback<T, C>() {
@Override
public void process(final PoolEntry<T, C> entry) {
if (entry.getUpdated() <= deadline) {
entry.close();
}
}
});
}closeIdle方法遍歷enumAvailable,挨個判斷最近的更新時間+idletime是否小于等于當前時間,是則執(zhí)行close
小結
HttpClientBuilder提供了evictExpiredConnections、evictIdleConnections方法,在build方法會在connManagerShared為false的前提下判斷是否開啟evictExpiredConnections或者evictIdleConnections,是則創(chuàng)建IdleConnectionEvictor并執(zhí)行start方法。IdleConnectionEvictor創(chuàng)建了一個thread,使用while循環(huán),每次循環(huán)sleep指定的sleepTimeMs時間,然后執(zhí)行connectionManager.closeExpiredConnections();對于maxIdleTimeMs大于0的,執(zhí)行connectionManager.closeIdleConnections(maxIdleTimeMs, TimeUnit.MILLISECONDS)。
以上就是httpclient evict操作源碼解讀的詳細內(nèi)容,更多關于httpclient evict操作的資料請關注腳本之家其它相關文章!
相關文章
springboot配置文件中敏感數(shù)據(jù)(賬號密碼)加密方式
這篇文章主要介紹了springboot配置文件中敏感數(shù)據(jù)(賬號密碼)加密方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
Java Spring動態(tài)生成Mysql存儲過程詳解
這篇文章主要介紹了Java Spring動態(tài)生成Mysql存儲過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06
基于Java編寫一個簡單的內(nèi)部網(wǎng)段掃描程序
這篇文章主要為大家詳細介紹了如何基于Java編寫一個簡單的內(nèi)部網(wǎng)段掃描程序,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解下2025-02-02
Java字符串拼接的五種方法及性能比較分析(從執(zhí)行100次到90萬次)
字符串拼接一般使用“+”,但是“+”不能滿足大批量數(shù)據(jù)的處理,Java中有以下五種方法處理字符串拼接及性能比較分析,感興趣的可以了解一下2021-12-12
SpringBoot如何統(tǒng)一清理數(shù)據(jù)
這篇文章主要介紹了SpringBoot如何統(tǒng)一清理數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
解決RestTemplate 請求接收自定義400+ 或500+錯誤
這篇文章主要介紹了解決RestTemplate 請求接收自定義400+ 或500+錯誤,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08

