欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

httpclient staleConnectionCheckEnabled獲取連接流程解析

 更新時間:2023年11月24日 09:29:47   作者:codecraft  
這篇文章主要為大家介紹了httpclient staleConnectionCheckEnabled獲取連接流程示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

本文主要研究一下httpclient的staleConnectionCheckEnabled

staleConnectionCheckEnabled

org/apache/http/client/config/RequestConfig.java

public class RequestConfig implements Cloneable {
    public static final RequestConfig DEFAULT = new Builder().build();
    private final boolean expectContinueEnabled;
    private final HttpHost proxy;
    private final InetAddress localAddress;
    private final boolean staleConnectionCheckEnabled;
    //......
    /**
     * Determines whether stale connection check is to be used. The stale
     * connection check can cause up to 30 millisecond overhead per request and
     * should be used only when appropriate. For performance critical
     * operations this check should be disabled.
     * <p>
     * Default: {@code false} since 4.4
     * </p>
     *
     * @deprecated (4.4) Use {@link
     *   org.apache.http.impl.conn.PoolingHttpClientConnectionManager#getValidateAfterInactivity()}
     */
    @Deprecated
    public boolean isStaleConnectionCheckEnabled() {
        return staleConnectionCheckEnabled;
    }   
    public static class Builder {
        private boolean expectContinueEnabled;
        private HttpHost proxy;
        private InetAddress localAddress;
        private boolean staleConnectionCheckEnabled;
        //......
        Builder() {
            super();
            this.staleConnectionCheckEnabled = false;
            this.redirectsEnabled = true;
            this.maxRedirects = 50;
            this.relativeRedirectsAllowed = true;
            this.authenticationEnabled = true;
            this.connectionRequestTimeout = -1;
            this.connectTimeout = -1;
            this.socketTimeout = -1;
            this.contentCompressionEnabled = true;
            this.normalizeUri = true;
        }        
        /**
         * @deprecated (4.4) Use {@link
         *   org.apache.http.impl.conn.PoolingHttpClientConnectionManager#setValidateAfterInactivity(int)}
         */
        @Deprecated
        public Builder setStaleConnectionCheckEnabled(final boolean staleConnectionCheckEnabled) {
            this.staleConnectionCheckEnabled = staleConnectionCheckEnabled;
            return this;
        }  
        //......
    }       
}
RequestConfig定義了staleConnectionCheckEnabled屬性,在4.4版本廢棄了,默認為false,替換設置是org.apache.http.impl.conn.PoolingHttpClientConnectionManager.setValidateAfterInactivity(int);Builder方法也提供了setStaleConnectionCheckEnabled方法

MainClientExec

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

public CloseableHttpResponse execute(
            final HttpRoute route,
            final HttpRequestWrapper request,
            final HttpClientContext context,
            final HttpExecutionAware execAware) throws IOException, HttpException {
        Args.notNull(route, "HTTP route");
        Args.notNull(request, "HTTP request");
        Args.notNull(context, "HTTP context");
        AuthState targetAuthState = context.getTargetAuthState();
        if (targetAuthState == null) {
            targetAuthState = new AuthState();
            context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, targetAuthState);
        }
        AuthState proxyAuthState = context.getProxyAuthState();
        if (proxyAuthState == null) {
            proxyAuthState = new AuthState();
            context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, proxyAuthState);
        }
        if (request instanceof HttpEntityEnclosingRequest) {
            RequestEntityProxy.enhance((HttpEntityEnclosingRequest) request);
        }
        Object userToken = context.getUserToken();
        final ConnectionRequest connRequest = connManager.requestConnection(route, userToken);
        if (execAware != null) {
            if (execAware.isAborted()) {
                connRequest.cancel();
                throw new RequestAbortedException("Request aborted");
            }
            execAware.setCancellable(connRequest);
        }
        final RequestConfig config = context.getRequestConfig();
        final HttpClientConnection managedConn;
        try {
            final int timeout = config.getConnectionRequestTimeout();
            managedConn = connRequest.get(timeout > 0 ? timeout : 0, TimeUnit.MILLISECONDS);
        } catch(final InterruptedException interrupted) {
            Thread.currentThread().interrupt();
            throw new RequestAbortedException("Request aborted", interrupted);
        } catch(final ExecutionException ex) {
            Throwable cause = ex.getCause();
            if (cause == null) {
                cause = ex;
            }
            throw new RequestAbortedException("Request execution failed", cause);
        }
        context.setAttribute(HttpCoreContext.HTTP_CONNECTION, managedConn);
        if (config.isStaleConnectionCheckEnabled()) {
            // validate connection
            if (managedConn.isOpen()) {
                this.log.debug("Stale connection check");
                if (managedConn.isStale()) {
                    this.log.debug("Stale connection detected");
                    managedConn.close();
                }
            }
        }
        final ConnectionHolder connHolder = new ConnectionHolder(this.log, this.connManager, managedConn);
        try {
            if (execAware != null) {
                execAware.setCancellable(connHolder);
            }
            HttpResponse response;
            for (int execCount = 1;; execCount++) {
                if (execCount > 1 && !RequestEntityProxy.isRepeatable(request)) {
                    throw new NonRepeatableRequestException("Cannot retry request " +
                            "with a non-repeatable request entity.");
                }
                if (execAware != null && execAware.isAborted()) {
                    throw new RequestAbortedException("Request aborted");
                }
                if (!managedConn.isOpen()) {
                    this.log.debug("Opening connection " + route);
                    try {
                        establishRoute(proxyAuthState, managedConn, route, request, context);
                    } catch (final TunnelRefusedException ex) {
                        if (this.log.isDebugEnabled()) {
                            this.log.debug(ex.getMessage());
                        }
                        response = ex.getResponse();
                        break;
                    }
                }
                context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
                response = requestExecutor.execute(request, managedConn, context);
                //......
            }
        }        
                //......
        //......
    }
MainClientExec的execute先通過connManager.requestConnection獲取ConnectionRequest,然后通過connRequest.get(timeout > 0 ? timeout : 0, TimeUnit.MILLISECONDS)獲取managedConn,之后判斷requestConfig的isStaleConnectionCheckEnabled,為true的話,會執(zhí)行連接的校驗,先判斷是否open,再判斷是否stale,為stale的話則執(zhí)行close;在managedConn關閉的時候,會通過establishRoute再進行連接

establishRoute

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

/**
     * Establishes the target route.
     */
    void establishRoute(
            final AuthState proxyAuthState,
            final HttpClientConnection managedConn,
            final HttpRoute route,
            final HttpRequest request,
            final HttpClientContext context) throws HttpException, IOException {
        final RequestConfig config = context.getRequestConfig();
        final int timeout = config.getConnectTimeout();
        final RouteTracker tracker = new RouteTracker(route);
        int step;
        do {
            final HttpRoute fact = tracker.toRoute();
            step = this.routeDirector.nextStep(route, fact);
            switch (step) {
            case HttpRouteDirector.CONNECT_TARGET:
                this.connManager.connect(
                        managedConn,
                        route,
                        timeout > 0 ? timeout : 0,
                        context);
                tracker.connectTarget(route.isSecure());
                break;
            case HttpRouteDirector.CONNECT_PROXY:
                this.connManager.connect(
                        managedConn,
                        route,
                        timeout > 0 ? timeout : 0,
                        context);
                final HttpHost proxy  = route.getProxyHost();
                tracker.connectProxy(proxy, route.isSecure() && !route.isTunnelled());
                break;
            case HttpRouteDirector.TUNNEL_TARGET: {
                final boolean secure = createTunnelToTarget(
                        proxyAuthState, managedConn, route, request, context);
                this.log.debug("Tunnel to target created.");
                tracker.tunnelTarget(secure);
            }   break;
            case HttpRouteDirector.TUNNEL_PROXY: {
                // The most simple example for this case is a proxy chain
                // of two proxies, where P1 must be tunnelled to P2.
                // route: Source -> P1 -> P2 -> Target (3 hops)
                // fact:  Source -> P1 -> Target       (2 hops)
                final int hop = fact.getHopCount()-1; // the hop to establish
                final boolean secure = createTunnelToProxy(route, hop, context);
                this.log.debug("Tunnel to proxy created.");
                tracker.tunnelProxy(route.getHopTarget(hop), secure);
            }   break;
            case HttpRouteDirector.LAYER_PROTOCOL:
                this.connManager.upgrade(managedConn, route, context);
                tracker.layerProtocol(route.isSecure());
                break;
            case HttpRouteDirector.UNREACHABLE:
                throw new HttpException("Unable to establish route: " +
                        "planned = " + route + "; current = " + fact);
            case HttpRouteDirector.COMPLETE:
                this.connManager.routeComplete(managedConn, route, context);
                break;
            default:
                throw new IllegalStateException("Unknown step indicator "
                        + step + " from RouteDirector.");
            }
        } while (step > HttpRouteDirector.COMPLETE);
    }
establishRoute方法在循環(huán)里頭通過connManager.connect建立連接

requestConnection

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

public ConnectionRequest requestConnection(
            final HttpRoute route,
            final Object state) {
        Args.notNull(route, "HTTP route");
        if (this.log.isDebugEnabled()) {
            this.log.debug("Connection request: " + format(route, state) + formatStats(route));
        }
        final Future<CPoolEntry> future = this.pool.lease(route, state, null);
        return new ConnectionRequest() {
            @Override
            public boolean cancel() {
                return future.cancel(true);
            }
            @Override
            public HttpClientConnection get(
                    final long timeout,
                    final TimeUnit timeUnit) throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException {
                final HttpClientConnection conn = leaseConnection(future, timeout, timeUnit);
                if (conn.isOpen()) {
                    final HttpHost host;
                    if (route.getProxyHost() != null) {
                        host = route.getProxyHost();
                    } else {
                        host = route.getTargetHost();
                    }
                    final SocketConfig socketConfig = resolveSocketConfig(host);
                    conn.setSocketTimeout(socketConfig.getSoTimeout());
                }
                return conn;
            }
        };
    }
PoolingHttpClientConnectionManager的requestConnection返回的ConnectionRequest的get方法是通過leaseConnection(future, timeout, timeUnit)來獲取連接的,而leaseConnection依賴的是pool.lease(route, state, null)返回的future

lease

org/apache/http/pool/AbstractConnPool.java

/**
     * {@inheritDoc}
     * <p>
     * Please note that this class does not maintain its own pool of execution
     * {@link Thread}s. Therefore, one <b>must</b> call {@link Future#get()}
     * or {@link Future#get(long, TimeUnit)} method on the {@link Future}
     * returned by this method in order for the lease operation to complete.
     */
    @Override
    public Future<E> lease(final T route, final Object state, final FutureCallback<E> callback) {
        Args.notNull(route, "Route");
        Asserts.check(!this.isShutDown, "Connection pool shut down");
        return new Future<E>() {
            private final AtomicBoolean cancelled = new AtomicBoolean(false);
            private final AtomicBoolean done = new AtomicBoolean(false);
            private final AtomicReference<E> entryRef = new AtomicReference<E>(null);
            @Override
            public boolean cancel(final boolean mayInterruptIfRunning) {
                if (done.compareAndSet(false, true)) {
                    cancelled.set(true);
                    lock.lock();
                    try {
                        condition.signalAll();
                    } finally {
                        lock.unlock();
                    }
                    if (callback != null) {
                        callback.cancelled();
                    }
                    return true;
                }
                return false;
            }
            @Override
            public boolean isCancelled() {
                return cancelled.get();
            }
            @Override
            public boolean isDone() {
                return done.get();
            }
            @Override
            public E get() throws InterruptedException, ExecutionException {
                try {
                    return get(0L, TimeUnit.MILLISECONDS);
                } catch (final TimeoutException ex) {
                    throw new ExecutionException(ex);
                }
            }
            @Override
            public E get(final long timeout, final TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
                for (;;) {
                    synchronized (this) {
                        try {
                            final E entry = entryRef.get();
                            if (entry != null) {
                                return entry;
                            }
                            if (done.get()) {
                                throw new ExecutionException(operationAborted());
                            }
                            final E leasedEntry = getPoolEntryBlocking(route, state, timeout, timeUnit, this);
                            if (validateAfterInactivity > 0)  {
                                if (leasedEntry.getUpdated() + validateAfterInactivity <= System.currentTimeMillis()) {
                                    if (!validate(leasedEntry)) {
                                        leasedEntry.close();
                                        release(leasedEntry, false);
                                        continue;
                                    }
                                }
                            }
                            if (done.compareAndSet(false, true)) {
                                entryRef.set(leasedEntry);
                                done.set(true);
                                onLease(leasedEntry);
                                if (callback != null) {
                                    callback.completed(leasedEntry);
                                }
                                return leasedEntry;
                            } else {
                                release(leasedEntry, true);
                                throw new ExecutionException(operationAborted());
                            }
                        } catch (final IOException ex) {
                            if (done.compareAndSet(false, true)) {
                                if (callback != null) {
                                    callback.failed(ex);
                                }
                            }
                            throw new ExecutionException(ex);
                        }
                    }
                }
            }
        };
    }
lease返回的future的get(final long timeout, final TimeUnit timeUnit)方法在一個循環(huán)里頭去獲取連接,內部是通過getPoolEntryBlocking獲取到leasedEntry,然后在validateAfterInactivity大于0的時候進行連接校驗,在leasedEntry.getUpdated() + validateAfterInactivity <= System.currentTimeMillis()的時候進行validate,校驗不成功的話進行關閉掉leasedEntry,然后release掉leasedEntry,然后繼續(xù)循環(huán)獲取下一個連接

小結

httpclient的RequestConfig提供了staleConnectionCheckEnabled屬性用于在請求獲取到連接的時候進行連接檢測,不過這個屬性在4.4版本被廢棄了,并默認設置為false,替換設置是org.apache.http.impl.conn.PoolingHttpClientConnectionManager.setValidateAfterInactivity(int),它是在ConnectionRequest的lease方法里頭根據(jù)leasedEntry.getUpdated() + validateAfterInactivity判斷是否需要校驗連接,若需要且校驗不通過則循環(huán)繼續(xù)獲??;而staleConnectionCheckEnabled則是在requestConnection之后根據(jù)RequestConfig的isStaleConnectionCheckEnabled來判斷,然后進行連接校驗,校驗不通過則關閉managedConn,最后會在判斷如果managedConn.isOpen()為false,則執(zhí)行establishRoute,在循環(huán)里頭通過connManager.connect來建立新連接。

以上就是httpclient staleConnectionCheckEnabled獲取連接流程解析的詳細內容,更多關于httpclient staleConnectionCheckEnabled的資料請關注腳本之家其它相關文章!

相關文章

  • 解決java壓縮圖片透明背景變黑色的問題

    解決java壓縮圖片透明背景變黑色的問題

    這篇文章主要介紹了解決java壓縮圖片透明背景變黑色的問題,需要的朋友可以參考下
    2014-04-04
  • JAVA實戰(zhàn)練習之圖書管理系統(tǒng)實現(xiàn)流程

    JAVA實戰(zhàn)練習之圖書管理系統(tǒng)實現(xiàn)流程

    隨著網(wǎng)絡技術的高速發(fā)展,計算機應用的普及,利用計算機對圖書館的日常工作進行管理勢在必行,本篇文章手把手帶你用Java實現(xiàn)一個圖書管理系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2021-10-10
  • SpringBoot默認包掃描機制與默認配置文件詳解

    SpringBoot默認包掃描機制與默認配置文件詳解

    這篇文章主要給大家詳細介紹了SpringBoot默認包掃描機制的原理和示例,以及SpringBoot默認配置文件介紹,文章通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-08-08
  • Mybatis一對多關聯(lián)關系映射實現(xiàn)過程解析

    Mybatis一對多關聯(lián)關系映射實現(xiàn)過程解析

    這篇文章主要介紹了Mybatis一對多關聯(lián)關系映射實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • SpringBoot集成JWT的工具類與攔截器實現(xiàn)方式

    SpringBoot集成JWT的工具類與攔截器實現(xiàn)方式

    這篇文章主要介紹了SpringBoot集成JWT的工具類與攔截器實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • SpringBoot實現(xiàn)過濾器Filter的三種方式

    SpringBoot實現(xiàn)過濾器Filter的三種方式

    過濾器Filter由Servlet提供,基于函數(shù)回調實現(xiàn)鏈式對網(wǎng)絡請求與響應的攔截與修改,本文講給大家詳細介紹SpringBoot實現(xiàn)過濾器Filter的三種方式,需要的朋友可以參考下
    2023-08-08
  • 手寫Java?LockSupport的示例代碼

    手寫Java?LockSupport的示例代碼

    LockSupport給我們提供了一個非常強大的功能,它是線程阻塞最基本的元語,他可以將一個線程阻塞也可以將一個線程喚醒,因此經常在并發(fā)的場景下進行使用。本文將用60行代碼實現(xiàn)手寫LockSupport,需要的可以參考一下
    2022-08-08
  • Spring 注入static屬性值方式

    Spring 注入static屬性值方式

    文本介紹了Spring如何從屬性文件給static屬性注入值,在寫一些與配置相關的工具類時常用。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • springboot使用redisTemplate操作lua腳本

    springboot使用redisTemplate操作lua腳本

    本文主要介紹了springboot使用redisTemplate操作lua腳本,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • Java8?Stream流根據(jù)多個字段去重

    Java8?Stream流根據(jù)多個字段去重

    這篇文章主要介紹了Java8?Stream流根據(jù)多個字段去重,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05

最新評論