有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪" />

亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

HttpClient的KeepAlive接口方法源碼解析

 更新時間:2023年10月11日 08:45:41   作者:codecraft  
這篇文章主要為大家介紹了HttpClient的KeepAlive接口方法源碼解析,
有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

本文主要研究一下HttpClient的KeepAlive

ConnectionKeepAliveStrategy

org/apache/http/conn/ConnectionKeepAliveStrategy.java

public interface ConnectionKeepAliveStrategy {
    /**
     * Returns the duration of time which this connection can be safely kept
     * idle. If the connection is left idle for longer than this period of time,
     * it MUST not reused. A value of 0 or less may be returned to indicate that
     * there is no suitable suggestion.
     *
     * When coupled with a {@link org.apache.http.ConnectionReuseStrategy}, if
     * {@link org.apache.http.ConnectionReuseStrategy#keepAlive(
     *   HttpResponse, HttpContext)} returns true, this allows you to control
     * how long the reuse will last. If keepAlive returns false, this should
     * have no meaningful impact
     *
     * @param response
     *            The last response received over the connection.
     * @param context
     *            the context in which the connection is being used.
     *
     * @return the duration in ms for which it is safe to keep the connection
     *         idle, or <=0 if no suggested duration.
     */
    long getKeepAliveDuration(HttpResponse response, HttpContext context);
}
ConnectionKeepAliveStrategy接口定義了getKeepAliveDuration方法,用于返回該connection空間多久以內(nèi)被復(fù)用是安全的

DefaultConnectionKeepAliveStrategy

org/apache/http/impl/client/DefaultConnectionKeepAliveStrategy.java

@Contract(threading = ThreadingBehavior.IMMUTABLE)
public class DefaultConnectionKeepAliveStrategy implements ConnectionKeepAliveStrategy {
    public static final DefaultConnectionKeepAliveStrategy INSTANCE = new DefaultConnectionKeepAliveStrategy();
    @Override
    public long getKeepAliveDuration(final HttpResponse response, final HttpContext context) {
        Args.notNull(response, "HTTP response");
        final HeaderElementIterator it = new BasicHeaderElementIterator(
                response.headerIterator(HTTP.CONN_KEEP_ALIVE));
        while (it.hasNext()) {
            final HeaderElement he = it.nextElement();
            final String param = he.getName();
            final String value = he.getValue();
            if (value != null && param.equalsIgnoreCase("timeout")) {
                try {
                    return Long.parseLong(value) * 1000;
                } catch(final NumberFormatException ignore) {
                }
            }
        }
        return -1;
    }
}
DefaultConnectionKeepAliveStrategy實現(xiàn)了ConnectionKeepAliveStrategy接口,它主要是從response的Keep-Alive的header讀取timeout參數(shù)

ConnectionReuseStrategy

org/apache/http/ConnectionReuseStrategy.java

public interface ConnectionReuseStrategy {
    /**
     * Decides whether a connection can be kept open after a request.
     * If this method returns {@code false}, the caller MUST
     * close the connection to correctly comply with the HTTP protocol.
     * If it returns {@code true}, the caller SHOULD attempt to
     * keep the connection open for reuse with another request.
     * <p>
     * One can use the HTTP context to retrieve additional objects that
     * may be relevant for the keep-alive strategy: the actual HTTP
     * connection, the original HTTP request, target host if known,
     * number of times the connection has been reused already and so on.
     * </p>
     * <p>
     * If the connection is already closed, {@code false} is returned.
     * The stale connection check MUST NOT be triggered by a
     * connection reuse strategy.
     * </p>
     *
     * @param response
     *          The last response received over that connection.
     * @param context   the context in which the connection is being
     *          used.
     *
     * @return {@code true} if the connection is allowed to be reused, or
     *         {@code false} if it MUST NOT be reused
     */
    boolean keepAlive(HttpResponse response, HttpContext context);
}
ConnectionReuseStrategy接口定義了keepAlive方法,用于判斷該connection是否保持連接繼續(xù)復(fù)用,還是直接關(guān)閉

DefaultClientConnectionReuseStrategy

org/apache/http/impl/client/DefaultClientConnectionReuseStrategy.java

public class DefaultClientConnectionReuseStrategy extends DefaultConnectionReuseStrategy {
    public static final DefaultClientConnectionReuseStrategy INSTANCE = new DefaultClientConnectionReuseStrategy();
    @Override
    public boolean keepAlive(final HttpResponse response, final HttpContext context) {
        final HttpRequest request = (HttpRequest) context.getAttribute(HttpCoreContext.HTTP_REQUEST);
        if (request != null) {
            final Header[] connHeaders = request.getHeaders(HttpHeaders.CONNECTION);
            if (connHeaders.length != 0) {
                final TokenIterator ti = new BasicTokenIterator(new BasicHeaderIterator(connHeaders, null));
                while (ti.hasNext()) {
                    final String token = ti.nextToken();
                    if (HTTP.CONN_CLOSE.equalsIgnoreCase(token)) {
                        return false;
                    }
                }
            }
        }
        return super.keepAlive(response, context);
    }
}
DefaultClientConnectionReuseStrategy繼承了DefaultConnectionReuseStrategy,其keepAlive方法先判斷Connection這個header的值是不是Close,若是則返回false,其他邏輯復(fù)用父類的方法

MainClientExec

org/apache/http/impl/execchain/MainClientExec.java

@Override
    public CloseableHttpResponse execute(
            final HttpRoute route,
            final HttpRequestWrapper request,
            final HttpClientContext context,
            final HttpExecutionAware execAware) throws IOException, HttpException {
            //......
               response = requestExecutor.execute(request, managedConn, context);
                // The connection is in or can be brought to a re-usable state.
                if (reuseStrategy.keepAlive(response, context)) {
                    // Set the idle duration of this connection
                    final long duration = keepAliveStrategy.getKeepAliveDuration(response, context);
                    if (this.log.isDebugEnabled()) {
                        final String s;
                        if (duration > 0) {
                            s = "for " + duration + " " + TimeUnit.MILLISECONDS;
                        } else {
                            s = "indefinitely";
                        }
                        this.log.debug("Connection can be kept alive " + s);
                    }
                    connHolder.setValidFor(duration, TimeUnit.MILLISECONDS);
                    connHolder.markReusable();
                } else {
                    connHolder.markNonReusable();
                }
            //......
    }
MainClientExec的execute方法會通過reuseStrategy.keepAlive判斷連接是否可以復(fù)用,是的話則通過keepAliveStrategy.getKeepAliveDuration來獲取keepAlive時間,同時設(shè)置setValidFor(keepalive)及markReusable

releaseConnection

org/apache/http/impl/conn/PoolingHttpClientConnectionManager.java

@Override
    public void releaseConnection(
            final HttpClientConnection managedConn,
            final Object state,
            final long keepalive, final TimeUnit timeUnit) {
        Args.notNull(managedConn, "Managed connection");
        synchronized (managedConn) {
            final CPoolEntry entry = CPoolProxy.detach(managedConn);
            if (entry == null) {
                return;
            }
            final ManagedHttpClientConnection conn = entry.getConnection();
            try {
                if (conn.isOpen()) {
                    final TimeUnit effectiveUnit = timeUnit != null ? timeUnit : TimeUnit.MILLISECONDS;
                    entry.setState(state);
                    entry.updateExpiry(keepalive, effectiveUnit);
                    if (this.log.isDebugEnabled()) {
                        final String s;
                        if (keepalive > 0) {
                            s = "for " + (double) effectiveUnit.toMillis(keepalive) / 1000 + " seconds";
                        } else {
                            s = "indefinitely";
                        }
                        this.log.debug("Connection " + format(entry) + " can be kept alive " + s);
                    }
                    conn.setSocketTimeout(0);
                }
            } finally {
                this.pool.release(entry, conn.isOpen() && entry.isRouteComplete());
                if (this.log.isDebugEnabled()) {
                    this.log.debug("Connection released: " + format(entry) + formatStats(entry.getRoute()));
                }
            }
        }
    }
PoolingHttpClientConnectionManager的releaseConnection方法在連接是open的時候執(zhí)行entry.updateExpiry(keepalive, effectiveUnit)

PoolEntry

org/apache/http/pool/PoolEntry.java

public synchronized void updateExpiry(final long time, final TimeUnit timeUnit) {
        Args.notNull(timeUnit, "Time unit");
        this.updated = System.currentTimeMillis();
        final long newExpiry;
        if (time > 0) {
            newExpiry = this.updated + timeUnit.toMillis(time);
        } else {
            newExpiry = Long.MAX_VALUE;
        }
        this.expiry = Math.min(newExpiry, this.validityDeadline);
    }
    public synchronized boolean isExpired(final long now) {
        return now >= this.expiry;
    }
它在keepalive大于0的時候更新newExpiry為當(dāng)前時間+keepalive時間,否則更新newExpiry為Long.MAX_VALUE,最后取newExpiry與validityDeadline的最小值作為entry的expiry;其isExpired方法用當(dāng)前時間與expiry對比,大于等于的返回true

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,是則執(zhí)行close

小結(jié)

HttpClient的MainClientExec的execute方法會通過reuseStrategy.keepAlive判斷連接是否可以復(fù)用,是的話則通過keepAliveStrategy.getKeepAliveDuration來獲取keepAlive時間,同時設(shè)置setValidFor(keepalive)及markReusable;IdleConnectionEvictor線程每隔指定時間會執(zhí)行closeExpired方法,它是依據(jù)當(dāng)前時間與entry的expiry時間進(jìn)行比較得出,而expiry時間則取newExpiry與validityDeadline的最小值,其中newExpiry的時間取決于keepAliveStrategy.getKeepAliveDuration,而validityDeadline取決于connTimeToLive值。若connTimeToLive值沒有設(shè)置則默認(rèn)為-1,那么validityDeadline的值是Long.MAX_VALUE,那么isExpired方法則取決于keepAliveStrategy.getKeepAliveDuration返回的值。若response的header沒有Keep-Alive或者Keep-Alive的header沒有timeout參數(shù)則keepAliveStrategy.getKeepAliveDuration返回-1(indefinitely),則newExpiry將是Long.MAX_VALUE。

默認(rèn)keepalive是開啟的,如果走systemProperties,且http.keepAlive設(shè)置為false,則ConnectionReuseStrategy會被設(shè)置為NoConnectionReuseStrategy(keepAlive方法返回false),連接歸還的時候會被直接關(guān)閉。

doc Keep-Alive

以上就是HttpClient的KeepAlive接口方法源碼解析的詳細(xì)內(nèi)容,更多關(guān)于HttpClient KeepAlive接口的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • springboot之如何同時連接多個redis

    springboot之如何同時連接多個redis

    這篇文章主要介紹了springboot之如何同時連接多個redis問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • MyBatis官方代碼生成工具給力(解放雙手)

    MyBatis官方代碼生成工具給力(解放雙手)

    這篇文章主要介紹了MyBatis官方代碼生成工具給力(解放雙手),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • java連接池Druid獲取連接getConnection示例詳解

    java連接池Druid獲取連接getConnection示例詳解

    這篇文章主要為大家介紹了java連接池Druid獲取連接getConnection示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • 圖解Java線程的生命周期

    圖解Java線程的生命周期

    本文主要介紹了Java中線程的5種狀態(tài)(新建(New)、就緒(Runable)、運(yùn)行(Running)、阻塞(Blocked)和死亡(Dead))之間的轉(zhuǎn)換圖解,有需要的朋友可以參考下
    2014-10-10
  • java中Hashmap的get方法使用

    java中Hashmap的get方法使用

    這篇文章主要介紹了java中Hashmap的get方法使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java如何通過流讀取圖片做base64編碼

    java如何通過流讀取圖片做base64編碼

    這篇文章主要介紹了java如何通過流讀取圖片做base64編碼問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • intelliJ idea 2023 配置Tomcat 8圖文教程

    intelliJ idea 2023 配置Tomcat 8圖文教程

    這篇文章主要介紹了intelliJ idea 2023 配置Tomcat 8教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • java8 stream 操作map根據(jù)key或者value排序的實現(xiàn)

    java8 stream 操作map根據(jù)key或者value排序的實現(xiàn)

    這篇文章主要介紹了java8 stream 操作map根據(jù)key或者value排序的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Java Dubbo框架知識點(diǎn)梳理

    Java Dubbo框架知識點(diǎn)梳理

    這篇文章主要介紹了Java Dubbo框架知識點(diǎn)梳理,通過詳細(xì)的文字講解和代碼實例,梳理了Dubbo這個框架,需要的朋友可以參考下
    2021-06-06
  • SpringBoot讀取多環(huán)境配置文件的幾種方式

    SpringBoot讀取多環(huán)境配置文件的幾種方式

    這篇文章主要給大家介紹了SpringBoot讀取多環(huán)境配置文件的幾種方式,文章通過代碼示例介紹的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下
    2023-10-10

最新評論