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方法,該方法會設(shè)置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方法,該方法會設(shè)置evictIdleConnections為true,同時設(shè)置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()。如果只是設(shè)置了evictExpiredConnections,則默認(rèn)sleepTime為10s,否則sleepTime及maxIdleTime都為設(shè)置的值(>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是否小于等于當(dāng)前時間,是則執(zhí)行close
小結(jié)
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操作源碼解讀的詳細(xì)內(nèi)容,更多關(guān)于httpclient evict操作的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
線程池ThreadPoolExecutor使用簡介與方法實例
今天小編就為大家分享一篇關(guān)于線程池ThreadPoolExecutor使用簡介與方法實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03基于Spring Mvc實現(xiàn)的Excel文件上傳下載示例
本篇文章主要介紹了基于Spring Mvc實現(xiàn)的Excel文件上傳下載示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02SpringBoot快速接入OpenAI大模型的方法(JDK8)
本文介紹了如何使用AI4J快速接入OpenAI大模型,并展示了如何實現(xiàn)流式與非流式的輸出,以及對函數(shù)調(diào)用的使用,AI4J支持JDK8,適用于多種應(yīng)用場景,包括Spring Boot項目,感興趣的朋友一起看看吧2025-02-02spring boot使用@Async異步注解的實現(xiàn)原理+源碼
通常我們都是采用多線程的方式來實現(xiàn)上述業(yè)務(wù)功能,但spring 提供更優(yōu)雅的方式來實現(xiàn)上述功能,就是@Async 異步注解,在方法上添加@Async,spring就會借助AOP,異步執(zhí)行方法,接下來通過本文給大家介紹spring boot異步注解的相關(guān)知識,一起看看吧2021-06-06