Apache HttpClient: setConnectTimeout() vs. setConnectionTimeToLive() vs. setSocketTimeout()

前端 未结 2 1526
栀梦
栀梦 2021-02-07 09:38

Can someone please explain what is the difference between these two:

client = HttpClientBuilder.create()
    .setConnectionTimeToLive(1, TimeUnit.MINUTES)
    .b         


        
2条回答
  •  -上瘾入骨i
    2021-02-07 10:37

    Connection Timeout: It is the timeout until a connection with the server is established.

    Socket Timeout: this is the time of inactivity to wait for packets[data] to receive.

    setConnectionRequestTimeout:

    However it is specific for configuring the connection manager. It is the time to fetch a connection from the connection pool.

    It returns the timeout in milliseconds used when requesting a connection from the connection manager. 0(zero) is used for an infinite timeout.

    setConnectionTimeToLive

    public final HttpClientBuilder setConnectionTimeToLive(long connTimeToLive, TimeUnit connTimeToLiveTimeUnit)

    Sets maximum time to live for persistent connections

    Please note this value can be overridden by the setConnectionManager(org.apache.http.conn.HttpClientConnectionManager) method.

    Since: 4.4

    Example: HttpClientStarter.java

    @Override
    public boolean start() {
    
        RegistryBuilder r = RegistryBuilder. create();
    
        // Register http and his plain socket factory
        final SocketFactory ss = getLevel().find(SocketFactory.class);
        ConnectionSocketFactory plainsf = new PlainConnectionSocketFactory() {
            @Override
            public Socket createSocket(HttpContext context) throws IOException {
                return ss.createSocket();
            }
        };
        r.register("http", plainsf);
    
        // Register https
        ConnectionSocketFactory sslfactory = getSSLSocketFactory();
        if (sslfactory != null) {
            r.register("https", getSSLSocketFactory());
        } else {
            log(Level.WARN, "ssl factory not found, won't manage https");
        }
    
        HttpClientBuilder builder = HttpClientBuilder.create();
        builder.setUserAgent(USERAGENT);
        builder.setConnectionTimeToLive(timeout, TimeUnit.SECONDS);
        builder.evictIdleConnections((long) timeout, TimeUnit.SECONDS);
    
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r.build());
        cm.setMaxTotal(maxConnect * 2);
        cm.setDefaultMaxPerRoute(2);
        cm.setValidateAfterInactivity(timeout * 1000);
        builder.setConnectionManager(cm);
    
        RequestConfig rc = RequestConfig.custom()
                .setConnectionRequestTimeout(timeout * 1000)
                .setConnectTimeout(timeout * 1000)
                .setSocketTimeout(timeout * 1000)
                .build();
        builder.setDefaultRequestConfig(rc);
    
        client = builder.build();
    
        return true;
    }
    

    Resource Link:

    1. HttpClientStarter.java

    2. HttpClient 4.x Timeout

    The HTTP specification does not determine how long a persistent connection may or should remain active. Some HTTP servers use a non-standard header, Keep-Alive, to tell clients the number of seconds they want to stay connected on the server side. HttClient will take advantage of this if this information is available. If the header information Keep-Alive does not exist in the response, HttpClient assumes the connection remains active indefinitely. However, many real-world HTTP servers are configured to discard persistent connections after certain periods of inactivity to conserve system resources, often without notification to the client.

    Here you can rewrite one, here is set to 5 seconds

    ConnectionKeepAliveStrategy keepAliveStrategy = new DefaultConnectionKeepAliveStrategy() {
                @Override
                public long getKeepAliveDuration(final HttpResponse response, final HttpContext context) {
                    long keepAlive = super.getKeepAliveDuration(response, context);
                    if (keepAlive == -1) {
                        keepAlive = 5000;
                    }
                    return keepAlive;
                }
            };
    

    Connection eviction policy

    The main disadvantage of a classic blocking I/O model is that network sockets respond to I/O events only when I/O operations are blocked. When a connection is released back to the manager, it can be kept alive without monitoring the status of the socket and responding to any I/O events. If the connection is closed on the server side, then the client connection can not detect changes in the connection status and shut down the local socket to respond properly.

    HttpClient tries to alleviate this problem by testing if the connection is outdated, which is no longer valid as it is already closed on the server side before using the connection that made the HTTP request. Outdated connection check is not 100% stable, but instead requires 10 to 30 milliseconds for each request execution. The only workable socket model thread solution that does not involve every free connection is to use a dedicated monitoring thread to reclaim the connection that is considered expired because of prolonged inactivity. Monitoring thread can periodically call ClientConnectionManager#closeExpiredConnections() method to close all expired connections, withdraw from the connection pool closed connection. It can also optionally call the ClientConnectionManager#closeIdleConnections() method to close all connections that have been idle for more than a given period of time.

    Resource Link:

    http://dev.dafan.info/detail/513285

提交回复
热议问题