httpclient源码分析之 PoolingHttpClientConnectionManager 获取连接 (转)
2021-03-06 06:29
标签:etc 修改 app lock 打开 manage features ssh asserts PoolingHttpClientConnectionManager是一个HttpClientConnection的连接池,可以为多线程提供并发请求服务。主要作用就是分配连接,回收连接等。同一个route的请求,会优先使用连接池提供的空闲长连接。 源码版本4.5.2,因为代码太多,很多不是自己关心的,为免看起来费力,这里代码贴的不全。省略代码的地方用省略号标注。 获取连接分两步,首先新建一个ConnectionRequest,在通过request.get得到HttpClientConnection。 这里的future是Future future = this.pool.lease(route, state, null);得到的。 读到这里,看起来拿到的entry要么是刚刚创建的热乎的,要么是没有过期的连接,要么是复用的池子中有效的永久连接。是这样的吗?再看一下复用的永久连接的情况: 判断连接是否可用: 了解下测试连接是否可用的过程,梳理一下调用链路: org.apache.http.impl.BHttpConnectionBase org.apache.http.impl.io.SessionInputBufferImpl org.apache.http.impl.conn.LoggingInputStream sun.security.ssl.AppInputStream sun.security.ssl.SSLSocketImpl sun.security.ssl.InputRecord java.net.SocketInputStream 以上,是对PoolingHttpClientConnectionManager从连接池中获取一个连接给用户的过程。用户拿到的连接有三种:新创建的;未过期的短连接;间隔检查的永久链接。 出处:https://www.cnblogs.com/shoren/p/httpclient-leaseConnection.html 其他: https://blog.csdn.net/u013905744/article/details/94714696 https://stackoverflow.com/questions/13837012/spring-resttemplate-timeout https://www.cnblogs.com/coderjinjian/p/9644923.html https://www.cnblogs.com/shoren/p/httpclient-leaseConnection.html https://www.cnblogs.com/shoren/p/http-connection.html https://blog.csdn.net/u014133299/article/details/80676147 https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-resttemplate httpclient源码分析之 PoolingHttpClientConnectionManager 获取连接 (转) 标签:etc 修改 app lock 打开 manage features ssh asserts 原文地址:https://www.cnblogs.com/guanbin-529/p/12897984.html
配置说明
public PoolingHttpClientConnectionManager(
final HttpClientConnectionOperator httpClientConnectionOperator,
final HttpConnectionFactory
获取连接
//org.apache.http.impl.conn.PoolingHttpClientConnectionManager
@Override
public ConnectionRequest requestConnection(
final HttpRoute route,
final Object state) {
......
//从连接池中获取一个CPoolEntry(Connection的包装类)
final Future
所以,CPoolEntry(ManagedHttpClientConnection的封装),实际是调用PoolingHttpClientConnectionManager的leaseConnection,通过future的get获得。
//org.apache.http.pool.AbstractConnPool
@Override
public Future
//如果往前validateAfterInactivity ms之内没有校验,则校验entry。校验不通过则关闭并释放,继续从连接池中获取entry。
//如果往前validateAfterInactivity ms之内有过校验,则无需再次校验
if (entry.getUpdated() + this.validateAfterInactivity
//org.apache.http.impl.conn.CPool
protected boolean validate(final CPoolEntry entry) {
return !entry.getConnection().isStale();
}
//org.apache.http.impl.BHttpConnectionBase
//判断连接是否不可用(go down)
public boolean isStale() {
//没有打开,即socket为空,则不可用
if (!isOpen()) {
return true;
}
try {
//socket链路有了,测试链路是否可用
//这里的测试方法是查看很短的时间内(这里是1ms),是否可以从输入流中读到数据
//如果测试结果返回-1说明不可用
final int bytesRead = fillInputBuffer(1);
return bytesRead
private int fillInputBuffer(final int timeout) throws IOException 不处理异常
public int fillBuffer() throws IOException 不处理异常
打印日志,不处理异常 @Override
public int read(final byte[] b, final int off, final int len) throws IOException {
try {
final int bytesRead = in.read(b, off, len);
if (bytesRead == -1) {
wire.input("end of stream");
} else if (bytesRead > 0) {
wire.input(b, off, bytesRead);
}
return bytesRead;
} catch (final IOException ex) {
wire.input("[read] I/O error: " + ex.getMessage());
throw ex;
}
}
public synchronized int read(byte[] var1, int var2, int var3) throws IOException 不处理异常
void readDataRecord(InputRecord var1) throws IOException 不处理异常
void read(InputStream var1, OutputStream var2) throws IOException
int read(byte b[], int off, int length, int timeout) throws IOException
通过socket读取数据,如果发生ConnectionResetException异常,则throw new SocketException("Connection reset");
需要注意,间隔检查的永久链接 如果在间隔时间(这里是2s)内,socket连接出现什么问题,是不知道的,因为没有进行检测。另外,检查链接是否可用的方法 isStale
,并不是100%靠谱的,即检测时出现SocketTimeoutException时,认为是可用的。而这时候,很有可能连接不可用,比如服务端关闭链接的情况。
文章标题:httpclient源码分析之 PoolingHttpClientConnectionManager 获取连接 (转)
文章链接:http://soscw.com/index.php/essay/60744.html