如何正確使用HttpClient以及restTemplate


 

import java.util.concurrent.TimeUnit;

import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    @Autowired
    private RestTemplateProperties restTemplateProperties;

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate(httpRequestFactory());
    }

    @Bean
    public ClientHttpRequestFactory httpRequestFactory() {
        return new HttpComponentsClientHttpRequestFactory(httpClient());
    }

    // pool監測線程,定期移除過期連接、空閑連接
/*
    public static class IdleConnectionMonitorThread extends Thread {

        private final HttpClientConnectionManager connMgr;

        public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {
            super();
            this.connMgr = connMgr;
        }

        @Override
        public void run() {
            try {
                while (true) {
                    synchronized (this) {
                        Thread.sleep(5000);
                        connMgr.closeExpiredConnections();
                        connMgr.closeIdleConnections(5, TimeUnit.SECONDS);
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
*/
    @Bean
    public HttpClient httpClient() {
        // 支持http和https
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory()).build();
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
        connectionManager.setMaxTotal(restTemplateProperties.getMaxTotal());
        connectionManager.setDefaultMaxPerRoute(restTemplateProperties.getDefaultMaxPerRoute());
        connectionManager.setValidateAfterInactivity(restTemplateProperties.getValidateAfterInactivity());

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(restTemplateProperties.getConnectTimeout())
                .setSocketTimeout(restTemplateProperties.getSocketTimeout())
                .setConnectionRequestTimeout(restTemplateProperties.getConnectionRequestTimeout()).build();

        // keep-alive策略
        ConnectionKeepAliveStrategy keepAliveStrategy = new ConnectionKeepAliveStrategy() {
            @Override
            public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
                // 如果服務端response返回了Keep-Alive header
                HeaderElementIterator it = new BasicHeaderElementIterator(
                        response.headerIterator(HTTP.CONN_KEEP_ALIVE));
                while (it.hasNext()) {
                    HeaderElement he = it.nextElement();
                    String param = he.getName();
                    String value = he.getValue();
                    if (value != null && param.equalsIgnoreCase("timeout")) {
                        try {
                            return Long.parseLong(value) * 1000;
                        } catch (NumberFormatException ignore) {
                        }
                    }
                }
                // 否則設置客戶端默認keep-alive超時時間
                return restTemplateProperties.getClientDefaultKeepAliveTime();
            }
        };

        /*
         Thread t = new IdleConnectionMonitorThread(connectionManager);
         t.setName("httpconnections-pool-evict-thread"); 
         t.start();
         */
        return HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .evictExpiredConnections()    //設置后台線程剔除失效連接
                .evictIdleConnections(restTemplateProperties.getMaxIdleTime(), TimeUnit.MILLISECONDS)
                .setKeepAliveStrategy(keepAliveStrategy).build();
    }
}

 

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix="resttemplate")
public class RestTemplateProperties {
    
    private Integer maxTotal;    //總連接數
    private Integer defaultMaxPerRoute; //單個路由最大連接數
    private Integer connectTimeout;        // 與遠程服務器建立連接的時間
    private Integer connectionRequestTimeout;    // 從connection manager獲取連接的超時時間
    private Integer socketTimeout;    // 建立連接之后,等待遠程服務器返回數據的時間,也就是兩個數據包(請求包和響應包)之間不活動的最大時間
    private Integer validateAfterInactivity;
    private Integer clientDefaultKeepAliveTime; //客戶端默認keep-alive時間
    private Integer maxIdleTime;    //連接最大空閑時間
    public Integer getMaxTotal() {
        return maxTotal;
    }
    public void setMaxTotal(Integer maxTotal) {
        this.maxTotal = maxTotal;
    }
    public Integer getDefaultMaxPerRoute() {
        return defaultMaxPerRoute;
    }
    public void setDefaultMaxPerRoute(Integer defaultMaxPerRoute) {
        this.defaultMaxPerRoute = defaultMaxPerRoute;
    }
    public Integer getConnectTimeout() {
        return connectTimeout;
    }
    public void setConnectTimeout(Integer connectTimeout) {
        this.connectTimeout = connectTimeout;
    }
    public Integer getConnectionRequestTimeout() {
        return connectionRequestTimeout;
    }
    public void setConnectionRequestTimeout(Integer connectionRequestTimeout) {
        this.connectionRequestTimeout = connectionRequestTimeout;
    }
    public Integer getSocketTimeout() {
        return socketTimeout;
    }
    public void setSocketTimeout(Integer socketTimeout) {
        this.socketTimeout = socketTimeout;
    }
    public Integer getValidateAfterInactivity() {
        return validateAfterInactivity;
    }
    public void setValidateAfterInactivity(Integer validateAfterInactivity) {
        this.validateAfterInactivity = validateAfterInactivity;
    }
    public Integer getClientDefaultKeepAliveTime() {
        return clientDefaultKeepAliveTime;
    }
    public void setClientDefaultKeepAliveTime(Integer clientDefaultKeepAliveTime) {
        this.clientDefaultKeepAliveTime = clientDefaultKeepAliveTime;
    }
    public Integer getMaxIdleTime() {
        return maxIdleTime;
    }
    public void setMaxIdleTime(Integer maxIdleTime) {
        this.maxIdleTime = maxIdleTime;
    }
    
}

 

resttemplate.max-total=2000
resttemplate.default-max-per-route=1000
resttemplate.connect-timeout=5000
resttemplate.connection-request-timeout=1000
resttemplate.socket-timeout=5000
resttemplate.validate-after-inactivity=2000
resttemplate.client-default-keep-alive-time=5000
resttemplate.max-idle-time=5000

 

參考: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html

           https://www.cnblogs.com/meiwangqing/p/10712829.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM