All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.csb.sdk.internel.HttpClientConnManager Maven / Gradle / Ivy

package com.alibaba.csb.sdk.internel;

import com.alibaba.csb.sdk.HttpCallerException;
import com.alibaba.csb.sdk.SdkLogger;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by wiseking on 18/6/19.
 */
public class HttpClientConnManager {
    // 设置是否使用连接池的开关 -Dhttp.caller.skip.connection.pool=true 不使用连接池
    public static final Boolean SKIP_CONN_POOL = Boolean.getBoolean("http.caller.skip.connection.pool");
    // 检查连接池中不可用的连接的间隔 (单位ms, 默认 100ms)
    private static final int VALIDATE_PERIOD = Integer.getInteger("http.caller.connection.validate.span", 100);
    // 清除连接池中过期或者长时间限制的连接的时间间隔 (单位ms, 默认 5000ms)
    private static final int CLEAN_PERIOD = Integer.getInteger("http.caller.connection.clean.span", 5000);
    private static final int MAX_CONNECTION_TIMEOUT = 2000;
    private static final int MAX_SOCKET_TIMEOUT = 90000;
    private static final int MAX_CR_TIMEOUT = 1000;
    private static final List SUPPORTED_CONNECTION_PARAMS = Arrays.asList("http.caller.connection.max",
            "http.caller.connection.timeout",
            "http.caller.connection.so.timeout",
            "http.caller.connection.cr.timeout",
            "http.caller.connection.async");


    public static CloseableHttpClient HTTP_CLIENT = null;
    private static PoolingHttpClientConnectionManager connMgr = null;

    static {
        try {
            if (!SKIP_CONN_POOL) {
                // 设置连接池
                connMgr = HttpClientFactory.createConnManager();
                // 设置连接池大小
                String maxConnStr = System.getProperty(SUPPORTED_CONNECTION_PARAMS.get(0));
                connMgr.setMaxTotal(maxConnStr == null ? 200 : Integer.parseInt(maxConnStr));
                connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());
                connMgr.setValidateAfterInactivity(VALIDATE_PERIOD);

                HTTP_CLIENT = HttpClientFactory.createCloseableHttpClient(connMgr);

                final IdleConnectionMonitorThread clearThread = new IdleConnectionMonitorThread(connMgr);
                clearThread.setDaemon(true);
                clearThread.start();
            } else {
                if (SdkLogger.isLoggable()) {
                    SdkLogger.print("[WARNING] skip using connection pool");
                }
            }
        } catch (HttpCallerException e) {
            HTTP_CLIENT = null;
            System.out.println("[WARNING] failed to create a pooled http client with the error : " + e.getMessage());
            if (SdkLogger.isLoggable()) {
                e.printStackTrace(System.out);
            }
        }
    }

    public static class IdleConnectionMonitorThread extends Thread {
        private final HttpClientConnectionManager connMgr;
        private volatile boolean shutdown;

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

        @Override
        public void run() {
            try {
                while (!shutdown) {
                    synchronized (this) {
                        wait(CLEAN_PERIOD);
                        // Close expired connections
                        connMgr.closeExpiredConnections();
                        // Optionally, close connections
                        // that have been idle longer than 30 sec
                        connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
                    }
                }
            } catch (InterruptedException ex) {
                // terminate
            }
        }

        public void shutdown() {
            shutdown = true;
            synchronized (this) {
                notifyAll();
            }
        }
    }


    public static RequestConfig.Builder createConnBuilder() {
        RequestConfig.Builder configBuilder = RequestConfig.custom();
        String CONN_TIMEOUT = System.getProperty(SUPPORTED_CONNECTION_PARAMS.get(1));
        String SO_TIMEOUT = System.getProperty(SUPPORTED_CONNECTION_PARAMS.get(2));
        String CR_TIMEOUT = System.getProperty(SUPPORTED_CONNECTION_PARAMS.get(3));

        // 设置连接超时
        int iconnTimeout = MAX_CONNECTION_TIMEOUT;
        if (CONN_TIMEOUT != null) {
            try {
                iconnTimeout = Integer.parseInt(CONN_TIMEOUT);
            } catch (Exception e) {
                // log it!
            }
        }
        configBuilder.setConnectTimeout(iconnTimeout);
        // 设置读取超时
        int isoTimeout = MAX_SOCKET_TIMEOUT;
        if (SO_TIMEOUT != null) {
            try {
                isoTimeout = Integer.parseInt(SO_TIMEOUT);
            } catch (Exception e) {
                // log it!
            }
        }
        configBuilder.setSocketTimeout(isoTimeout);
        // 设置从连接池获取连接实例的超时
        int icrTimeout = MAX_CR_TIMEOUT;
        if (CR_TIMEOUT != null) {
            try {
                icrTimeout = Integer.parseInt(CR_TIMEOUT);
            } catch (Exception e) {
                // log it!
            }
        }
        configBuilder.setConnectionRequestTimeout(icrTimeout);
        // 在提交请求之前 测试连接是否可用
        // 不要使用下面这个过期的方法,它的效率会很低
        //configBuilder.setStaleConnectionCheckEnabled(true);

        // 设置cookie ignore
        configBuilder.setCookieSpec(CookieSpecs.IGNORE_COOKIES);
        //DefaultHttpParams.getDefaultParams().setParameter("http.protocol.cookie-policy", CookiePolicy.BROWSER_COMPATIBILITY);
        return configBuilder;
    }

    public static RequestConfig.Builder createConnBuilder(Map params) {
        RequestConfig.Builder connBuilder = createConnBuilder();
        for (Map.Entry es : params.entrySet()) {
            if (!SUPPORTED_CONNECTION_PARAMS.contains(es.getKey())) {
                throw new IllegalArgumentException("error connection param:" + es.getKey());
            }
            if (connMgr != null && es.getKey().equals(SUPPORTED_CONNECTION_PARAMS.get(0))) {
                connMgr.setMaxTotal(Integer.parseInt(es.getValue()));

            } else if (es.getKey().equals(SUPPORTED_CONNECTION_PARAMS.get(1))) {
                connBuilder.setConnectTimeout(Integer.parseInt(es.getValue()));
            } else if (es.getKey().equals(SUPPORTED_CONNECTION_PARAMS.get(2))) {
                connBuilder.setSocketTimeout(Integer.parseInt(es.getValue()));
            } else if (es.getKey().equals(SUPPORTED_CONNECTION_PARAMS.get(3))) {
                connBuilder.setConnectionRequestTimeout(Integer.parseInt(es.getValue()));
            }
            HttpClientHelper.printDebugInfo(String.format("set %s as %s", es.getKey(), es.getValue()));
        }

        return connBuilder;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy