| @@ -1,6 +1,8 @@ | |||||
| package me.chanjar.weixin.common.util.http; | package me.chanjar.weixin.common.util.http; | ||||
| import me.chanjar.weixin.common.util.StringUtils; | |||||
| import java.io.IOException; | |||||
| import java.util.concurrent.TimeUnit; | |||||
| import org.apache.http.annotation.NotThreadSafe; | import org.apache.http.annotation.NotThreadSafe; | ||||
| import org.apache.http.auth.AuthScope; | import org.apache.http.auth.AuthScope; | ||||
| import org.apache.http.auth.UsernamePasswordCredentials; | import org.apache.http.auth.UsernamePasswordCredentials; | ||||
| @@ -21,8 +23,7 @@ import org.apache.http.impl.client.HttpClients; | |||||
| import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; | import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; | ||||
| import org.apache.http.protocol.HttpContext; | import org.apache.http.protocol.HttpContext; | ||||
| import java.io.IOException; | |||||
| import java.util.concurrent.TimeUnit; | |||||
| import me.chanjar.weixin.common.util.StringUtils; | |||||
| /** | /** | ||||
| * httpclient 连接管理器 | * httpclient 连接管理器 | ||||
| @@ -33,7 +34,7 @@ public class DefaultApacheHttpHttpClientBuilder implements ApacheHttpClientBuild | |||||
| private int connectionTimeout = 5000; | private int connectionTimeout = 5000; | ||||
| private int soTimeout = 5000; | private int soTimeout = 5000; | ||||
| private int idleConnTimeout = 60000; | private int idleConnTimeout = 60000; | ||||
| private int checkWaitTime = 5000; | |||||
| private int checkWaitTime = 60000; | |||||
| private int maxConnPerHost = 10; | private int maxConnPerHost = 10; | ||||
| private int maxTotalConn = 50; | private int maxTotalConn = 50; | ||||
| private String userAgent; | private String userAgent; | ||||
| @@ -74,86 +75,95 @@ public class DefaultApacheHttpHttpClientBuilder implements ApacheHttpClientBuild | |||||
| return new DefaultApacheHttpHttpClientBuilder(); | return new DefaultApacheHttpHttpClientBuilder(); | ||||
| } | } | ||||
| @Override | |||||
| public ApacheHttpClientBuilder httpProxyHost(String httpProxyHost) { | public ApacheHttpClientBuilder httpProxyHost(String httpProxyHost) { | ||||
| this.httpProxyHost = httpProxyHost; | this.httpProxyHost = httpProxyHost; | ||||
| return this; | return this; | ||||
| } | } | ||||
| @Override | |||||
| public ApacheHttpClientBuilder httpProxyPort(int httpProxyPort) { | public ApacheHttpClientBuilder httpProxyPort(int httpProxyPort) { | ||||
| this.httpProxyPort = httpProxyPort; | this.httpProxyPort = httpProxyPort; | ||||
| return this; | return this; | ||||
| } | } | ||||
| @Override | |||||
| public ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername) { | public ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername) { | ||||
| this.httpProxyUsername = httpProxyUsername; | this.httpProxyUsername = httpProxyUsername; | ||||
| return this; | return this; | ||||
| } | } | ||||
| @Override | |||||
| public ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword) { | public ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword) { | ||||
| this.httpProxyPassword = httpProxyPassword; | this.httpProxyPassword = httpProxyPassword; | ||||
| return this; | return this; | ||||
| } | } | ||||
| @Override | |||||
| public ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory) { | public ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory) { | ||||
| this.sslConnectionSocketFactory = sslConnectionSocketFactory; | this.sslConnectionSocketFactory = sslConnectionSocketFactory; | ||||
| return this; | return this; | ||||
| } | } | ||||
| public IdleConnectionMonitorThread getIdleConnectionMonitorThread() { | public IdleConnectionMonitorThread getIdleConnectionMonitorThread() { | ||||
| return idleConnectionMonitorThread; | |||||
| return this.idleConnectionMonitorThread; | |||||
| } | } | ||||
| private void prepare() { | private void prepare() { | ||||
| Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() | Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() | ||||
| .register("http", plainConnectionSocketFactory) | |||||
| .register("https", sslConnectionSocketFactory) | |||||
| .register("http", this.plainConnectionSocketFactory) | |||||
| .register("https", this.sslConnectionSocketFactory) | |||||
| .build(); | .build(); | ||||
| connectionManager = new PoolingHttpClientConnectionManager(registry); | |||||
| connectionManager.setMaxTotal(maxTotalConn); | |||||
| connectionManager.setDefaultMaxPerRoute(maxConnPerHost); | |||||
| connectionManager.setDefaultSocketConfig( | |||||
| this.connectionManager = new PoolingHttpClientConnectionManager(registry); | |||||
| this.connectionManager.setMaxTotal(this.maxTotalConn); | |||||
| this.connectionManager.setDefaultMaxPerRoute(this.maxConnPerHost); | |||||
| this.connectionManager.setDefaultSocketConfig( | |||||
| SocketConfig.copy(SocketConfig.DEFAULT) | SocketConfig.copy(SocketConfig.DEFAULT) | ||||
| .setSoTimeout(soTimeout) | |||||
| .setSoTimeout(this.soTimeout) | |||||
| .build() | .build() | ||||
| ); | ); | ||||
| idleConnectionMonitorThread = new IdleConnectionMonitorThread(connectionManager, idleConnTimeout, checkWaitTime); | |||||
| idleConnectionMonitorThread.setDaemon(true); | |||||
| idleConnectionMonitorThread.start(); | |||||
| this.idleConnectionMonitorThread = new IdleConnectionMonitorThread( | |||||
| this.connectionManager, this.idleConnTimeout, this.checkWaitTime); | |||||
| this.idleConnectionMonitorThread.setDaemon(true); | |||||
| this.idleConnectionMonitorThread.start(); | |||||
| httpClientBuilder = HttpClients.custom() | |||||
| .setConnectionManager(connectionManager) | |||||
| this.httpClientBuilder = HttpClients.custom() | |||||
| .setConnectionManager(this.connectionManager) | |||||
| .setDefaultRequestConfig( | .setDefaultRequestConfig( | ||||
| RequestConfig.custom() | RequestConfig.custom() | ||||
| .setSocketTimeout(soTimeout) | |||||
| .setConnectTimeout(connectionTimeout) | |||||
| .setConnectionRequestTimeout(connectionRequestTimeout) | |||||
| .setSocketTimeout(this.soTimeout) | |||||
| .setConnectTimeout(this.connectionTimeout) | |||||
| .setConnectionRequestTimeout(this.connectionRequestTimeout) | |||||
| .build() | .build() | ||||
| ) | ) | ||||
| .setRetryHandler(httpRequestRetryHandler); | |||||
| .setRetryHandler(this.httpRequestRetryHandler); | |||||
| if (StringUtils.isNotBlank(httpProxyHost) && StringUtils.isNotBlank(httpProxyUsername)) { | |||||
| if (StringUtils.isNotBlank(this.httpProxyHost) | |||||
| && StringUtils.isNotBlank(this.httpProxyUsername)) { | |||||
| // 使用代理服务器 需要用户认证的代理服务器 | // 使用代理服务器 需要用户认证的代理服务器 | ||||
| CredentialsProvider credsProvider = new BasicCredentialsProvider(); | CredentialsProvider credsProvider = new BasicCredentialsProvider(); | ||||
| credsProvider.setCredentials( | credsProvider.setCredentials( | ||||
| new AuthScope(httpProxyHost, httpProxyPort), | |||||
| new UsernamePasswordCredentials(httpProxyUsername, httpProxyPassword)); | |||||
| httpClientBuilder.setDefaultCredentialsProvider(credsProvider); | |||||
| new AuthScope(this.httpProxyHost, this.httpProxyPort), | |||||
| new UsernamePasswordCredentials(this.httpProxyUsername, | |||||
| this.httpProxyPassword)); | |||||
| this.httpClientBuilder.setDefaultCredentialsProvider(credsProvider); | |||||
| } | } | ||||
| if (StringUtils.isNotBlank(userAgent)) { | |||||
| httpClientBuilder.setUserAgent(userAgent); | |||||
| if (StringUtils.isNotBlank(this.userAgent)) { | |||||
| this.httpClientBuilder.setUserAgent(this.userAgent); | |||||
| } | } | ||||
| } | } | ||||
| @Override | |||||
| public CloseableHttpClient build() { | public CloseableHttpClient build() { | ||||
| if (!prepared) { | |||||
| if (!this.prepared) { | |||||
| prepare(); | prepare(); | ||||
| prepared = true; | |||||
| this.prepared = true; | |||||
| } | } | ||||
| return httpClientBuilder.build(); | |||||
| return this.httpClientBuilder.build(); | |||||
| } | } | ||||
| public static class IdleConnectionMonitorThread extends Thread { | public static class IdleConnectionMonitorThread extends Thread { | ||||
| @@ -172,11 +182,12 @@ public class DefaultApacheHttpHttpClientBuilder implements ApacheHttpClientBuild | |||||
| @Override | @Override | ||||
| public void run() { | public void run() { | ||||
| try { | try { | ||||
| while (!shutdown) { | |||||
| while (!this.shutdown) { | |||||
| synchronized (this) { | synchronized (this) { | ||||
| wait(checkWaitTime); | |||||
| connMgr.closeExpiredConnections(); | |||||
| connMgr.closeIdleConnections(idleConnTimeout, TimeUnit.MILLISECONDS); | |||||
| wait(this.checkWaitTime); | |||||
| this.connMgr.closeExpiredConnections(); | |||||
| this.connMgr.closeIdleConnections(this.idleConnTimeout, | |||||
| TimeUnit.MILLISECONDS); | |||||
| } | } | ||||
| } | } | ||||
| } catch (InterruptedException ignore) { | } catch (InterruptedException ignore) { | ||||
| @@ -190,7 +201,7 @@ public class DefaultApacheHttpHttpClientBuilder implements ApacheHttpClientBuild | |||||
| } | } | ||||
| public void shutdown() { | public void shutdown() { | ||||
| shutdown = true; | |||||
| this.shutdown = true; | |||||
| synchronized (this) { | synchronized (this) { | ||||
| notifyAll(); | notifyAll(); | ||||
| } | } | ||||