httpclient evict操作源码解读

 更新时间:2023年10月07日 16:31:35   作者:codecraft  
这篇文章主要为大家介绍了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,是则创建IdleConnectionEvictor,往closeablesCopy注册shutdown及awaitTermination,最后执行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创建了一个thread,使用while循环,每次循环sleep指定的sleepTimeMs时间,然后执行connectionManager.closeExpiredConnections();对于maxIdleTimeMs大于0的,执行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值),是则执行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是否小于等于当前时间,是则执行close

小结

HttpClientBuilder提供了evictExpiredConnections、evictIdleConnections方法,在build方法会在connManagerShared为false的前提下判断是否开启evictExpiredConnections或者evictIdleConnections,是则创建IdleConnectionEvictor并执行start方法。IdleConnectionEvictor创建了一个thread,使用while循环,每次循环sleep指定的sleepTimeMs时间,然后执行connectionManager.closeExpiredConnections();对于maxIdleTimeMs大于0的,执行connectionManager.closeIdleConnections(maxIdleTimeMs, TimeUnit.MILLISECONDS)。

以上就是httpclient evict操作源码解读的详细内容,更多关于httpclient evict操作的资料请关注脚本之家其它相关文章!

相关文章

  • java ImmutableMap的使用说明

    java ImmutableMap的使用说明

    这篇文章主要介绍了java ImmutableMap的使用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 详解使用Spring MVC统一异常处理实战

    详解使用Spring MVC统一异常处理实战

    本篇文章主要介绍了详解使用Spring MVC统一异常处理实战,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • 关于SpringBoot配置文件application.properties的路径问题

    关于SpringBoot配置文件application.properties的路径问题

    这篇文章主要介绍了关于SpringBoot配置文件application.properties的路径问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • java生成抽样随机数的多种算法

    java生成抽样随机数的多种算法

    本文主要介绍了java生成抽样随机数的多种算法,主要是基于random库函数的,有需要的可以了解一下。
    2016-10-10
  • Spring中Bean的三种实例化方式详解

    Spring中Bean的三种实例化方式详解

    这篇文章主要给大家介绍了关于Spring中实例化bean的三种方式:构造方法、静态工厂和实例工厂,对我们学习有一定的参考价值,需要的小伙伴可以了解一下
    2022-06-06
  • Springboot整合activemq的方法步骤

    Springboot整合activemq的方法步骤

    这篇文章主要介绍了Springboot整合activemq的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • 利用Springboot+vue实现图片上传至数据库并显示的全过程

    利用Springboot+vue实现图片上传至数据库并显示的全过程

    最近遇到个需求,需要将图片在前端上传到服务器进行保存,然后读取到前端进行展示,这篇文章主要给大家介绍了关于利用Springboot+vue实现图片上传至数据库并显示的相关资料,需要的朋友可以参考下
    2023-04-04
  • Java数据结构和算法之冒泡,选择和插入排序算法

    Java数据结构和算法之冒泡,选择和插入排序算法

    这篇文章主要为大家介绍了Java冒泡,选择和插入排序算法 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • JAVA设计模式之责任链模式详解

    JAVA设计模式之责任链模式详解

    这篇文章主要介绍了JAVA设计模式之责任链模式详解,需要的朋友可以参考下
    2015-04-04
  • Spring中的动态数据源解读

    Spring中的动态数据源解读

    这篇文章主要介绍了关于Spring中的动态数据源解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06

最新评论