下面列出了怎么用org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* httpRequestFactory.
*
* @return
*/
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager(
30, TimeUnit.SECONDS);
// max connection
pollingConnectionManager.setMaxTotal(constants.getRestTemplateMaxTotal());
pollingConnectionManager.setDefaultMaxPerRoute(constants.getRestTemplateMaxPerRoute());
HttpClientBuilder httpClientBuilder = HttpClients.custom();
httpClientBuilder.setConnectionManager(pollingConnectionManager);
// add Keep-Alive
httpClientBuilder
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
HttpClient httpClient = httpClientBuilder.build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
new HttpComponentsClientHttpRequestFactory(httpClient);
clientHttpRequestFactory.setReadTimeout(constants.getHttp_read_timeOut());
clientHttpRequestFactory.setConnectTimeout(constants.getHttp_connect_timeOut());
return clientHttpRequestFactory;
}
@Override
public long getKeepAliveDuration(
HttpResponse response,
HttpContext context) {
// If there's a Keep-Alive timeout directive in the response and it's
// shorter than our configured max, honor that. Otherwise go with the
// configured maximum.
long duration = DefaultConnectionKeepAliveStrategy.INSTANCE
.getKeepAliveDuration(response, context);
if (0 < duration && duration < maxIdleTime) {
return duration;
}
return maxIdleTime;
}
@Override
public long getKeepAliveDuration(
HttpResponse response,
HttpContext context) {
// If there's a Keep-Alive timeout directive in the response and it's
// shorter than our configured max, honor that. Otherwise go with the
// configured maximum.
long duration = DefaultConnectionKeepAliveStrategy.INSTANCE
.getKeepAliveDuration(response, context);
if (0 < duration && duration < maxIdleTime) {
return duration;
}
return maxIdleTime;
}
static CloseableHttpClient makeCloseableHttpClient(Duration timeout, Duration keepAlive) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout((int) timeout.toMillis()) // establishment of connection
.setConnectionRequestTimeout((int) timeout.toMillis()) // connection from connection manager
.setSocketTimeout((int) timeout.toMillis()) // waiting for data
.build();
ConnectionKeepAliveStrategy keepAliveStrategy =
new DefaultConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
long keepAliveMillis = super.getKeepAliveDuration(response, context);
if (keepAliveMillis == -1) {
keepAliveMillis = keepAlive.toMillis();
}
return keepAliveMillis;
}
};
return VespaHttpClientBuilder.createWithBasicConnectionManager()
.setUserAgent("service-monitor")
.setKeepAliveStrategy(keepAliveStrategy)
.disableAutomaticRetries()
.setDefaultRequestConfig(requestConfig)
.build();
}
private CloseableHttpClient buildHttpClient(NomadApiConfiguration config) {
return HttpClientBuilder.create()
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
final long serverKeepAlive = super.getKeepAliveDuration(response, context);
return serverKeepAlive > 0 ? serverKeepAlive : 60000;
}
})
.setRetryHandler(new DefaultHttpRequestRetryHandler() {
@Override
protected boolean handleAsIdempotent(HttpRequest request) {
return true;
}
})
.setSSLContext(buildSslContext(config.getTls()))
.setSSLHostnameVerifier(new NomadHostnameVerifier())
.build();
}
@Test
public void testHttpRequestGet() throws Exception {
RequestConfig.Builder req = RequestConfig.custom();
req.setConnectTimeout(5000);
req.setConnectionRequestTimeout(5000);
req.setRedirectsEnabled(false);
req.setSocketTimeout(5000);
req.setExpectContinueEnabled(false);
HttpGet get = new HttpGet("http://127.0.0.1:54322/login");
get.setConfig(req.build());
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setDefaultMaxPerRoute(5);
HttpClientBuilder builder = HttpClients.custom();
builder.disableAutomaticRetries();
builder.disableRedirectHandling();
builder.setConnectionTimeToLive(5, TimeUnit.SECONDS);
builder.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE);
builder.setConnectionManager(cm);
CloseableHttpClient client = builder.build();
String s = client.execute(get, new ResponseHandler<String>() {
@Override
public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
assertEquals(301, response.getStatusLine().getStatusCode());
return "success";
}
});
assertEquals("success", s);
}
@Override
public CloseableHttpClient build() throws Exception {
HttpClientBuilder builder = HttpClients.custom();
builder.useSystemProperties();
builder
.setDefaultSocketConfig(SocketConfig.custom()
.setTcpNoDelay(true)
.setSoKeepAlive(true)
.build()
)
.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE);
HostnameVerifier hostnameVerifier = sslVerificationMode.verifier();
TrustStrategy trustStrategy = sslVerificationMode.trustStrategy();
KeyStore trustStore = agentTruststore();
SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
if (trustStore != null || trustStrategy != null) {
sslContextBuilder.loadTrustMaterial(trustStore, trustStrategy);
}
KeyStore keystore = agentKeystore();
if (keystore != null) {
sslContextBuilder.loadKeyMaterial(keystore, agentKeystorePassword);
}
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifier);
builder.setSSLSocketFactory(sslConnectionSocketFactory);
return builder.build();
}
/**
* Get a new CloseableHttpClient
*
* @return CloseableHttpClient
*/
public static CloseableHttpClient newHttpClient() {
final SocketConfig socketConfig = SocketConfig.custom()
.setSoKeepAlive(Boolean.TRUE).setTcpNoDelay(Boolean.TRUE)
.setSoTimeout(SOCKET_TIMEOUT_MS).build();
final PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();
manager.setDefaultMaxPerRoute(MAX_HOSTS);
manager.setMaxTotal(MAX_HOSTS);
manager.setDefaultSocketConfig(socketConfig);
final RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(CONNECTION_TIMEOUT_MS)
.setCookieSpec(CookieSpecs.IGNORE_COOKIES)
.setStaleConnectionCheckEnabled(Boolean.FALSE)
.setSocketTimeout(SOCKET_TIMEOUT_MS).build();
final CloseableHttpClient client = HttpClients
.custom()
.disableRedirectHandling()
.setConnectionManager(manager)
.setDefaultRequestConfig(requestConfig)
.setConnectionReuseStrategy(
new DefaultConnectionReuseStrategy())
.setConnectionBackoffStrategy(new DefaultBackoffStrategy())
.setRetryHandler(
new DefaultHttpRequestRetryHandler(MAX_RETRIES, false))
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy())
.build();
return client;
}
@Bean
public CloseableHttpClient closeableHttpClient() {
List<Header> headers = new ArrayList<>();
headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04"));
headers.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));
headers.add(new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"));
headers.add(new BasicHeader("Connection", "Keep-Alive"));
// 配置HTTPS支持
Registry<ConnectionSocketFactory> socketFactoryRegistry = null;
SSLContext sslContext = null;
try {
// 1. setup a Trust Strategy that allows all certificates.
TrustStrategy acceptingTrustStrategy = (chain, authType) -> true;
sslContext = org.apache.http.ssl.SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
// 2. don't check Host names, either.
// -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
// 3. here's the special part:
// -- need to create an SSL Socket Factory, to use our weakened "trust strategy";
// -- and create a Registry, to register it.
//
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslSocketFactory)
.build();
} catch (Exception e) {
log.error("Echo create httpClient SSL error", e);
}
// 4. now, we create connection-manager using our Registry.
// -- allows multi-threaded use
PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(Objects.requireNonNull(socketFactoryRegistry));;
poolingConnectionManager.setMaxTotal(echoProperties.getPoolMaxSize()); // 连接池最大连接数
poolingConnectionManager.setDefaultMaxPerRoute(echoProperties.getDefaultMaxPerRoute()); // 每个路由的并发
// 自定义连接管理
return HttpClients.custom().setConnectionManager(poolingConnectionManager).setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
long keepAlive = super.getKeepAliveDuration(response, context);
if (keepAlive == -1) {
keepAlive = echoProperties.getKeepAlive().toMillis();
}
return keepAlive;
}
}).setRetryHandler(new DefaultHttpRequestRetryHandler(echoProperties.getRetryCount(), echoProperties.isEnableRequestSentRetry()))
.setSSLContext(sslContext)
.setDefaultHeaders(headers).build();
}
/**
* ClientHttpRequestFactory接口的另一种实现方式(推荐使用),即:
* HttpComponentsClientHttpRequestFactory:底层使用Httpclient连接池的方式创建Http连接请求
* @return HttpComponentsClientHttpRequestFactory
*/
@Bean
public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory(){
//Httpclient连接池,长连接保持30秒
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);
//设置总连接数
connectionManager.setMaxTotal(1000);
//设置同路由的并发数
connectionManager.setDefaultMaxPerRoute(1000);
//设置header
List<Header> headers = new ArrayList<Header>();
headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04"));
headers.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));
headers.add(new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"));
headers.add(new BasicHeader("Connection", "keep-alive"));
//创建HttpClient
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connectionManager)
.setDefaultHeaders(headers)
.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) //设置重试次数
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) //设置保持长连接
.build();
//创建HttpComponentsClientHttpRequestFactory实例
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(httpClient);
//设置客户端和服务端建立连接的超时时间
requestFactory.setConnectTimeout(5000);
//设置客户端从服务端读取数据的超时时间
requestFactory.setReadTimeout(5000);
//设置从连接池获取连接的超时时间,不宜过长
requestFactory.setConnectionRequestTimeout(200);
//缓冲请求数据,默认为true。通过POST或者PUT大量发送数据时,建议将此更改为false,以免耗尽内存
requestFactory.setBufferRequestBody(false);
return requestFactory;
}
/**
* ClientHttpRequestFactory接口的另一种实现方式(推荐使用),即:
* HttpComponentsClientHttpRequestFactory:底层使用Httpclient连接池的方式创建Http连接请求
* @return HttpComponentsClientHttpRequestFactory
*/
@Bean
public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory(){
//Httpclient连接池,长连接保持30秒
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);
//设置总连接数
connectionManager.setMaxTotal(1000);
//设置同路由的并发数
connectionManager.setDefaultMaxPerRoute(1000);
//设置header
List<Header> headers = new ArrayList<Header>();
headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04"));
headers.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));
headers.add(new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"));
headers.add(new BasicHeader("Connection", "keep-alive"));
//创建HttpClient
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connectionManager)
.setDefaultHeaders(headers)
.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) //设置重试次数
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) //设置保持长连接
.build();
//创建HttpComponentsClientHttpRequestFactory实例
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(httpClient);
//设置客户端和服务端建立连接的超时时间
requestFactory.setConnectTimeout(5000);
//设置客户端从服务端读取数据的超时时间
requestFactory.setReadTimeout(5000);
//设置从连接池获取连接的超时时间,不宜过长
requestFactory.setConnectionRequestTimeout(200);
//缓冲请求数据,默认为true。通过POST或者PUT大量发送数据时,建议将此更改为false,以免耗尽内存
requestFactory.setBufferRequestBody(false);
return requestFactory;
}
private CloseableHttpClient getHttpClient() {
//注册访问协议相关的Socket工厂
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", SSLConnectionSocketFactory.getSocketFactory())
.build();
//HttpConnectionFactory:配置写请求/解析响应处理器
HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connectionFactory = new ManagedHttpClientConnectionFactory(
DefaultHttpRequestWriterFactory.INSTANCE,
DefaultHttpResponseParserFactory.INSTANCE
);
//DNS解析器
DnsResolver dnsResolver = SystemDefaultDnsResolver.INSTANCE;
//创建连接池管理器
PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(socketFactoryRegistry, connectionFactory, dnsResolver);
//设置默认的socket参数
manager.setDefaultSocketConfig(SocketConfig.custom().setTcpNoDelay(true).build());
manager.setMaxTotal(300);//设置最大连接数。高于这个值时,新连接请求,需要阻塞,排队等待
//路由是对MaxTotal的细分。
// 每个路由实际最大连接数默认值是由DefaultMaxPerRoute控制。
// MaxPerRoute设置的过小,无法支持大并发:ConnectionPoolTimeoutException:Timeout waiting for connection from pool
manager.setDefaultMaxPerRoute(200);//每个路由的最大连接
manager.setValidateAfterInactivity(5 * 1000);//在从连接池获取连接时,连接不活跃多长时间后需要进行一次验证,默认为2s
//配置默认的请求参数
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(2 * 1000)//连接超时设置为2s
.setSocketTimeout(5 * 1000)//等待数据超时设置为5s
.setConnectionRequestTimeout(2 * 1000)//从连接池获取连接的等待超时时间设置为2s
// .setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("192.168.0.2", 1234))) //设置代理
.build();
CloseableHttpClient closeableHttpClient = HttpClients.custom()
.setConnectionManager(manager)
.setConnectionManagerShared(false)//连接池不是共享模式,这个共享是指与其它httpClient是否共享
.evictIdleConnections(60, TimeUnit.SECONDS)//定期回收空闲连接
.evictExpiredConnections()//回收过期连接
.setConnectionTimeToLive(60, TimeUnit.SECONDS)//连接存活时间,如果不设置,则根据长连接信息决定
.setDefaultRequestConfig(defaultRequestConfig)//设置默认的请求参数
.setConnectionReuseStrategy(DefaultConnectionReuseStrategy.INSTANCE)//连接重用策略,即是否能keepAlive
.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)//长连接配置,即获取长连接生产多长时间
.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))//设置重试次数,默认为3次;当前是禁用掉
.build();
/**
*JVM停止或重启时,关闭连接池释放掉连接
*/
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
closeableHttpClient.close();
log.info("http client closed");
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
});
return closeableHttpClient;
}
@Override
public HttpClient createHttpClient(FilterConfig filterConfig) {
final String serviceRole = filterConfig.getInitParameter(PARAMETER_SERVICE_ROLE);
HttpClientBuilder builder;
GatewayConfig gatewayConfig = (GatewayConfig) filterConfig.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
GatewayServices services = (GatewayServices) filterConfig.getServletContext()
.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
if (gatewayConfig != null && gatewayConfig.isMetricsEnabled()) {
MetricsService metricsService = services.getService(ServiceType.METRICS_SERVICE);
builder = metricsService.getInstrumented(HttpClientBuilder.class);
} else {
builder = HttpClients.custom();
}
// Conditionally set a custom SSLContext
SSLContext sslContext = createSSLContext(services, filterConfig, serviceRole);
if(sslContext != null) {
builder.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext));
}
if (Boolean.parseBoolean(System.getProperty(GatewayConfig.HADOOP_KERBEROS_SECURED))) {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UseJaasCredentials());
Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
.register(AuthSchemes.SPNEGO, new KnoxSpnegoAuthSchemeFactory(true))
.build();
builder.setDefaultAuthSchemeRegistry(authSchemeRegistry)
.setDefaultCookieStore(new HadoopAuthCookieStore(gatewayConfig))
.setDefaultCredentialsProvider(credentialsProvider);
} else {
builder.setDefaultCookieStore(new NoCookieStore());
}
builder.setKeepAliveStrategy( DefaultConnectionKeepAliveStrategy.INSTANCE );
builder.setConnectionReuseStrategy( DefaultConnectionReuseStrategy.INSTANCE );
builder.setRedirectStrategy( new NeverRedirectStrategy() );
builder.setRetryHandler( new NeverRetryHandler() );
int maxConnections = getMaxConnections( filterConfig );
builder.setMaxConnTotal( maxConnections );
builder.setMaxConnPerRoute( maxConnections );
builder.setDefaultRequestConfig(getRequestConfig(filterConfig, serviceRole));
// See KNOX-1530 for details
builder.disableContentCompression();
return builder.build();
}