`
想起要学好java
  • 浏览: 8759 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

HttpClient连接池

    博客分类:
  • http
 
阅读更多

连接管理:

两个主机之间建立的过程是很复杂的,包括了两个终端之间许多数据包的交换,会消耗掉大量的时间。对于很小的HTTP报文传输,TCP/IP的握手环节也是必不可少的。如果已有的链接能够重复使用,来执行多个请求,将会加大程序的数据吞吐量。HttpClient完全地支持连接持久化。

 

连接池管理器 Pool Connection Manager:

PoolingHttpClientConnectionManager 是一个管理客户端连接更复杂的实现。它为执行多线程的连接请求提供服务。对于每个基本的路由,连接都是池管理的。对于路由的请求,连接器在池中有可用的持久性连接,

将被从池中取出连接服务,而不是创建一个新的连接。对每个基本路由,PoolingHttpClientConnectionManager保持着一个最大限制的连接数。使用HttpClient.close() 释放连接。 

当使用PoolingClientConnectionManager 时可以使用多线程来同时执行多个请求。如果池中没有可用的连接,请求将会被阻塞,直到有可用的连接。如果在一定的时间内不能被响应,将会抛出ConnectionPoolTimeoutException异常。

 

代码示例:

import java.io.IOException;

import java.io.InputStream;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

 

import javax.net.ssl.HostnameVerifier;

import javax.net.ssl.SSLContext;

 

import org.apache.commons.io.IOUtils;

import org.apache.http.HttpResponse;

import org.apache.http.NameValuePair;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.CookieStore;

import org.apache.http.client.config.RequestConfig;

import org.apache.http.client.entity.UrlEncodedFormEntity;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.client.protocol.HttpClientContext;

import org.apache.http.config.Registry;

import org.apache.http.config.RegistryBuilder;

import org.apache.http.conn.HttpClientConnectionManager;

import org.apache.http.conn.socket.ConnectionSocketFactory;

import org.apache.http.conn.socket.PlainConnectionSocketFactory;

import org.apache.http.conn.ssl.DefaultHostnameVerifier;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;

import org.apache.http.impl.client.BasicCookieStore;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import org.apache.http.message.BasicNameValuePair;

import org.apache.http.ssl.SSLContexts;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

public class HttpClientUtils {

private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);

 

private final HttpClientContext context = new HttpClientContext(); // 初始化上下文实例

private final HttpClientConnectionManager manager = builderPoolConnectionManager(); // 定义连接池管理变量

 

private final String CHAR_SET = "UTF-8";

 

public HttpClientUtils() {

CookieStore cookieStore = new BasicCookieStore();

context.setCookieStore(cookieStore);

}

 

public HttpClientConnectionManager builderPoolConnectionManager() {

final SSLContext context = SSLContexts.createSystemDefault();

final HostnameVerifier verifier = new DefaultHostnameVerifier();

// 自定义注册器,既可以发送http请求,也可以发送https请求

final Registry<ConnectionSocketFactory> register = RegistryBuilder.<ConnectionSocketFactory>create()

.register("http", PlainConnectionSocketFactory.INSTANCE)

.register("https", new SSLConnectionSocketFactory(context, verifier)).build();

 

PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(

register);

poolingHttpClientConnectionManager.setMaxTotal(200); // 设置连接池的最大连接数

poolingHttpClientConnectionManager.setDefaultMaxPerRoute(poolingHttpClientConnectionManager.getMaxTotal()); // 一个路由的最大连接数

return poolingHttpClientConnectionManager;

}

 

public CloseableHttpClient buildHttpClient() {

RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(3000) // 从池中获取请求的时间

.setConnectTimeout(2000) // 连接到服务器的时间

.setSocketTimeout(5000).build(); // 读取信息时间

 

// 如果使用了代理,请打开注释

// HttpHost proxy = new HttpHost("127.0.0.1" , 2924) ;

// HttpRoutePlanner httpRoutePlanner = new HttpRoutePlanner() {

// @Override

// public HttpRoute determineRoute(HttpHost httpHost, HttpRequest httpRequest,

// HttpContext httpContext) throws HttpException {

// return new HttpRoute(httpHost ,proxy);

// }

// };

CloseableHttpClient build = HttpClients.custom().setRetryHandler(DefaultHttpRequestRetryHandler.INSTANCE)

.setDefaultRequestConfig(config).setConnectionManagerShared(true).setConnectionManager(manager)

// .setRoutePlanner(httpRoutePlanner) 设置路由

.build();

 

return build;

}

 

public String post(String url, Map<String, String> params) {

HttpPost post = new HttpPost(url);

String resp = null;

// 这里每次拿到的是池内的一个空闲连接,而不是新建 的连接

CloseableHttpClient httpClient = new HttpClientUtils().buildHttpClient();

try {

try {

if (params != null) {

List<NameValuePair> nvps = new ArrayList<NameValuePair>();

for (Map.Entry<String, String> param : params.entrySet()) {

nvps.add(new BasicNameValuePair(param.getKey(), param.getValue()));

}

post.setEntity(new UrlEncodedFormEntity(nvps, CHAR_SET));

}

 

HttpResponse response = httpClient.execute(post);

InputStream input = response.getEntity().getContent();

resp = IOUtils.toString(input);

input.close();// 释放连接,以便下个请求复用

} catch (ClientProtocolException e) {

logger.error(e.getMessage(), e);

} catch (IOException e) {

logger.error(e.getMessage(), e);

} catch (Exception e) {

logger.error(e.getMessage(), e);

}

} finally {

if (post != null) {

post.releaseConnection();

}

}

 

return resp;

}

}

 

连接池使用注意事项:

1. 连接池中连接都是在发起请求的时候建立,并且都是长连接

2. HttpResponse input.close();作用就是将用完的连接释放,下次请求可以复用,这里特别注意的是,如果不使用in.close();而仅仅使用httpClient.close();结果就是连接会被关闭,并且不能被复用,这样就失去了采用连接池的意义。

3. 连接池释放连接的时候,并不会直接对TCP连接的状态有任何改变,只是维护了两个Set,leased和avaliabled,leased代表被占用的连接集合,avaliabled代表可用的连接的集合,释放连接的时候仅仅是将连接从leased中remove掉了,并把连接放到avaliabled集合中。

 

对RequestConfig里timeout的解释:

RequestConfig config = RequestConfig.custom()

                                    .setConnectionRequestTimeout(3000)  //从池中获取请求的时间

                                    .setConnectTimeout(2000)   //连接到服务器的时间

                                    .setSocketTimeout(5000).build(); //读取信息时间

setConnectTimeout:设置连接超时时间,单位毫秒。ConnectTimeoutException

setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。ConnectionPoolTimeout

setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。SocketTimeoutException

 

更详细的说明可以参考:

https://blog.csdn.net/ll641058431/article/details/79566277

分享到:
评论

相关推荐

    HttpAsyncClient 异步httpClient和同步httpClient连接池的工具类 包含jar

    HttpAsyncClient连接池的使用,项目中频繁发送http请求,同步http阻塞主线程,影响性能,使用 HttpAsyncClient可使性能提高,这里配合连接池使用,效果更好,同时还附带同步httpClient的连接池使用

    HttpCient连接池Demo

    HttpClient连接池是网络编程中一个重要的优化手段,它允许我们重用已经建立的HTTP连接,减少每次请求时的建立和关闭连接的开销,从而提高应用程序的性能和效率。Apache HttpClient库提供了这样的功能,让我们能够...

    HTTPClient工具类,完整

    HTTPClient工具类,完整,HTTPClient工具类,完整,HTTPClient工具类,完整HTTPClient工具类,完整,HTTPClient工具类,完整

    连接池实现原理及效率测试

    《连接池实现原理及效率测试》 连接池是数据库应用中的一个重要概念,它在系统设计中扮演着提高性能、优化资源利用的关键角色。本文将深入探讨连接池的实现原理,并通过实际测试分析其效率。 首先,我们需要理解...

    springboot中注解配置连接池

    在Spring Boot应用中,连接池是管理数据库连接的关键组件,它能提高数据库操作的效率和应用程序的性能。本文将深入探讨如何使用注解配置在Spring Boot中设置连接池。 首先,Spring Boot默认集成了多种数据库连接池...

    连接池研究1

    4. **HttpClient连接池管理** - HttpClient默认使用长连接,Tomcat中,默认的最大长连接时间为`connectionTimeout`。 - 如果手动调用`releaseConnection`,在`ManagedClientConnectionImpl`中会关闭socket,而如果...

    httpClient工具类

    封装好的httpClient工具类里面包含了get 和 post两种请求

    HttpConnectionManager.java

    Httpclient连接池

    使用java的HttpClient实现多线程并发

    静态初始化HttpClient和连接池管理器: ```java static { // 创建连接池管理器 cm = new PoolingHttpClientConnectionManager(); // 设置整个连接池的最大连接数 cm.setMaxTotal(200); // 设置每个路由上的默认...

    基于java开发的NIO+多线程实现聊天室+源码+项目解析(毕业设计&课程设计&项目开发)

    HttpClient连接池 Spring依赖注入 lombok简化POJO开发 原子变量 内置锁 CompletionService log4j+slf4j日志 实现的功能 登录注销 单聊 群聊 客户端提交任务,下载图片并显示 上线下线公告 在线用户记录 批量下载豆瓣...

    java多线程程序设计:Java NIO+多线程实现聊天室

    HttpClient连接池 Spring依赖注入 lombok简化POJO开发 原子变量 内置锁 CompletionService log4j+slf4j日志 实现的功能 登录注销 单聊 群聊 客户端提交任务,下载图片并显示 上线下线公告 在线用户记录 批量下载豆瓣...

    Http连接池工具类

    两个主机建立连接的过程是很复杂的一个过程,涉及到多个数据包...一般情况下,普通使用HttpClient已经能满足我们的需求,不过有时候,在我们需要高并发大量的请求网络的时候,还是用“连接池”这样的概念能提升吞吐量。

    Java NIO+多线程实现聊天室

    HttpClient连接池 Spring依赖注入 lombok简化POJO开发 原子指标 内置锁 竣工服务 log4j+slf4j日志 实现的功能 登录注销 单聊 群聊 客户端提交任务,下载图片并显示 上线下线公告 在线用户记录 批量下载豆瓣电影的...

    HttpClientUtil工具类发送get和post请求,支持http和https,支持发送文件

    HttpClientUtil可能需要配置连接池的大小、超时时间等参数,以适应不同的应用场景。 综上所述,HttpClientUtil工具类在IT应用中扮演着关键角色,简化了HTTP和HTTPS请求的实现,特别是发送文件这样的复杂操作。通过...

    httpclient.jar包下载

    1. **连接管理**:HttpClient通过HttpConnectionManager接口控制HTTP连接的创建、复用和关闭,有效地管理连接池,避免了频繁建立新连接带来的性能开销。 2. **请求和响应模型**:HttpClient使用HttpRequest和...

    httpclient3.1 javadoc chm版

    HttpClient 3.1支持连接池,可以复用已建立的连接,提高性能。使用HttpConnectionManager来管理连接池,如SingleClientConnManager或MultiThreadedHttpConnectionManager。 五、重定向处理 HttpClient可以自动处理...

    HttpClient4.2.1版本的Jar包

    HttpClient 4.2.1是该项目的一个稳定版本,它包含了对HTTP协议的全面支持,包括基本的GET、POST请求,以及更复杂的重定向处理、Cookie管理、连接池等功能。 HttpClient 4.2.1版本引入了一些重要的改进和修复,以...

    httpclient-4.5jar包

    HttpClient 4.5提供了PoolingHttpClientConnectionManager,用于管理连接池。开发者可以设定最大连接数、每个路由的最大连接数,以及超时时间。连接池的使用可以显著减少建立新连接的开销,提高性能。 五、异步操作...

    Java开发基于多线程和NIO实现聊天室源码+项目说明(含服务端+客户端).zip

    - HttpClient连接池 - Spring依赖注入 - lombok简化POJO开发 - 原子变量 - 内置锁 - CompletionService - log4j+slf4j日志 - 实现的功能 - 登录注销 - 单聊 - 群聊 - 客户端提交任务,下载图片并显示 -...

Global site tag (gtag.js) - Google Analytics