springboot整合http连接池
近段时间需要优化原有的http调用,原有的http调用是直接使用HttpClient进行调用,没有交给spring去管理,也没有清理过期链接的线程,这里记录下使用springboot如何配置HttpClient。①httpclient配置类,在其中可以配置http连接池最大链接数,并发数,超时时间,代理等。③进行调用,这里暂时提供get请求,post请求可以自己封装。②清理失效的http链接。
·
近段时间需要优化原有的http调用,原有的http调用是直接使用HttpClient进行调用,没有交给spring去管理,也没有清理过期链接的线程,这里记录下使用springboot如何配置HttpClient。下面直接放代码。
①httpclient配置类,在其中可以配置http连接池最大链接数,并发数,超时时间,代理等。
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpClientConfig {
private static final Logger logger = LoggerFactory.getLogger(HttpClientConfig.class);
@Value("${http.maxTotal}")
private Integer maxTotal;
@Value("${http.defaultMaxPerRoute}")
private Integer defaultMaxPerRoute;
@Value("${http.connectTimeout}")
private Integer connectTimeout;
@Value("${http.connectionRequestTimeout}")
private Integer connectionRequestTimeout;
@Value("${http.socketTimeout}")
private Integer socketTimeout;
/**
* 首先实例化一个连接池管理器,设置最大连接数、并发连接数
*
* @return
*/
@Bean(name = "httpClientConnectionManager")
public PoolingHttpClientConnectionManager getHttpClientConnectionManager() {
PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
//最大连接数
httpClientConnectionManager.setMaxTotal(maxTotal);
//并发数
httpClientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
return httpClientConnectionManager;
}
/**
* 实例化连接池,设置连接池管理器。
* 这里需要以参数形式注入上面实例化的连接池管理器
*
* @param httpClientConnectionManager
* @return
*/
@Bean(name = "httpClientBuilder")
public HttpClientBuilder getHttpClientBuilder(@Qualifier("httpClientConnectionManager") PoolingHttpClientConnectionManager httpClientConnectionManager) {
//HttpClientBuilder中的构造方法被protected修饰,所以这里不能直接使用new来实例化一个HttpClientBuilder,可以使用HttpClientBuilder提供的静态方法create()来获取HttpClientBuilder对象
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.setConnectionManager(httpClientConnectionManager);
return httpClientBuilder;
}
/**
* 注入连接池,用于获取httpClient
*
* @param httpClientBuilder
* @return
*/
@Bean(name = "httpClient")
public CloseableHttpClient getCloseableHttpClient(@Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder) {
return httpClientBuilder.build();
}
/**
* Builder是RequestConfig的一个内部类
* 通过RequestConfig的custom方法来获取到一个Builder对象
* 设置builder的连接信息
* 这里还可以设置proxy,cookieSpec等属性。有需要的话可以在此设置
*
* @return
*/
@Bean(name = "builder")
public RequestConfig.Builder getBuilder() {
RequestConfig.Builder builder = RequestConfig.custom();
return builder.setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout)
.setSocketTimeout(socketTimeout);
}
/**
* 使用builder构建一个RequestConfig对象
*
* @param builder
* @return
*/
@Bean
public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder) {
return builder.build();
}
}
②清理失效的http链接
@Component
public class IdleConnectionEvictor extends Thread {
@Autowired
private HttpClientConnectionManager httpClientConnectionManager;
private volatile boolean shutdown;
public IdleConnectionEvictor() {
super();
super.start();
}
@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(5000);
// 关闭失效的连接
httpClientConnectionManager.closeExpiredConnections();
httpClientConnectionManager.closeIdleConnections(30L, TimeUnit.SECONDS);
}
}
} catch (InterruptedException ex) {
// 结束
}
}
//关闭清理无效连接的线程
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}
③进行调用,这里暂时提供get请求,post请求可以自己封装
@Service
public class HttpClientService {
private static final Logger logger = LoggerFactory.getLogger(HttpClientService.class);
@Autowired
private CloseableHttpClient httpClient;
@Autowired
private RequestConfig requestConfig;
/**
* get请求
*
* @return
*/
public String doGet(String url, String charset) {
CloseableHttpResponse response = null;
try {
//发送get请求
HttpGet request = new HttpGet(url);
request.setConfig(requestConfig);
response = httpClient.execute(request);
/**请求发送成功,并得到响应**/
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
/**读取服务器返回过来的json字符串数据**/
String strResult = EntityUtils.toString(response.getEntity());
strResult = new String(strResult.getBytes(charset), "utf-8");
return strResult;
}
} catch (IOException e) {
logger.error("http调用出错:{}",e.getMessage())
} finally {
try {
if (response != null){
response.close();
}
}catch (IOException e){
logger.error("关闭链接出错:{}",e.getMessage());
}
}
return null;
}
}
④配置文件
#http配置服务
#最大连接数
http.maxTotal = 300
#并发数
http.defaultMaxPerRoute = 300
#创建连接的最长时间
http.connectTimeout=3000
更多推荐
已为社区贡献8条内容
所有评论(0)