如何正确使用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

原文地址:https://www.cnblogs.com/lyhero11/p/12767745.html