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

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

There is a newer version: 1.1.5.11
Show newest version
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 = -1;
  private static final int MAX_SOCKET_TIMEOUT = -1;
  private static final int MAX_CR_TIMEOUT = -1;
  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 maxConn = System.getProperty(SUPPORTED_CONNECTION_PARAMS.get(0));
        if (maxConn != null) {
          try {
            int imaxConn = Integer.parseInt(maxConn);
            connMgr.setMaxTotal(imaxConn);
            connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());
          } catch (Exception e) {
            // log it!
            throw new HttpCallerException(String.format("[ERROR] CSB-SDK failed to create connection pool with %d connections", maxConn));
          }
        }
        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 - 2024 Weber Informatics LLC | Privacy Policy