public class PoolingClientConnectionManager implements ClientConnectionManager, ConnPoolControl<HttpRoute> { private final Log log = LogFactory.getLog(getClass()); private final SchemeRegistry schemeRegistry; private final HttpConnPool pool; private final ClientConnectionOperator operator; /** the custom-configured DNS lookup mechanism. */ private final DnsResolver dnsResolver; public PoolingClientConnectionManager(final SchemeRegistry schreg) { this(schreg, -1, TimeUnit.MILLISECONDS); } public PoolingClientConnectionManager(final SchemeRegistry schreg,final DnsResolver dnsResolver) { this(schreg, -1, TimeUnit.MILLISECONDS,dnsResolver); } public PoolingClientConnectionManager() { this(SchemeRegistryFactory.createDefault()); } public PoolingClientConnectionManager( final SchemeRegistry schemeRegistry, final long timeToLive, final TimeUnit tunit) { this(schemeRegistry, timeToLive, tunit, new SystemDefaultDnsResolver()); } public PoolingClientConnectionManager(final SchemeRegistry schemeRegistry, final long timeToLive, final TimeUnit tunit, final DnsResolver dnsResolver) { super(); Args.notNull(schemeRegistry, "Scheme registry"); Args.notNull(dnsResolver, "DNS resolver"); this.schemeRegistry = schemeRegistry; this.dnsResolver = dnsResolver; this.operator = createConnectionOperator(schemeRegistry); this.pool = new HttpConnPool(this.log, this.operator, 2, 20, timeToLive, tunit); } @Override protected void finalize() throws Throwable { try { shutdown(); } finally { super.finalize(); } }
class HttpConnPool extends AbstractConnPool<HttpRoute, OperatedClientConnection, HttpPoolEntry> { private static final AtomicLong COUNTER = new AtomicLong(); private final Log log; private final long timeToLive; private final TimeUnit tunit; public HttpConnPool(final Log log, final ClientConnectionOperator connOperator, final int defaultMaxPerRoute, final int maxTotal, final long timeToLive, final TimeUnit tunit) { super(new InternalConnFactory(connOperator), defaultMaxPerRoute, maxTotal); this.log = log; this.timeToLive = timeToLive; this.tunit = tunit; } @Override protected HttpPoolEntry createEntry(final HttpRoute route, final OperatedClientConnection conn) { final String id = Long.toString(COUNTER.getAndIncrement()); return new HttpPoolEntry(this.log, id, route, conn, this.timeToLive, this.tunit); } static class InternalConnFactory implements ConnFactory<HttpRoute, OperatedClientConnection> { private final ClientConnectionOperator connOperator; InternalConnFactory(final ClientConnectionOperator connOperator) { this.connOperator = connOperator; } public OperatedClientConnection create(final HttpRoute route) throws IOException { return connOperator.createConnection(); } } }
public abstract class AbstractConnPool<T, C, E extends PoolEntry<T, C>> implements ConnPool<T, E>, ConnPoolControl<T> { private final Lock lock; private final ConnFactory<T, C> connFactory; private final Map<T, RouteSpecificPool<T, C, E>> routeToPool; private final Set<E> leased; private final LinkedList<E> available; private final LinkedList<PoolEntryFuture<E>> pending; private final Map<T, Integer> maxPerRoute; private volatile boolean isShutDown; private volatile int defaultMaxPerRoute; private volatile int maxTotal; public AbstractConnPool( final ConnFactory<T, C> connFactory, final int defaultMaxPerRoute, final int maxTotal) { super(); this.connFactory = Args.notNull(connFactory, "Connection factory"); this.defaultMaxPerRoute = Args.notNegative(defaultMaxPerRoute, "Max per route value"); this.maxTotal = Args.notNegative(maxTotal, "Max total value"); this.lock = new ReentrantLock(); this.routeToPool = new HashMap<T, RouteSpecificPool<T, C, E>>(); this.leased = new HashSet<E>(); this.available = new LinkedList<E>(); this.pending = new LinkedList<PoolEntryFuture<E>>(); this.maxPerRoute = new HashMap<T, Integer>(); }
class HttpPoolEntry extends PoolEntry<HttpRoute, OperatedClientConnection> { private final Log log; private final RouteTracker tracker; public HttpPoolEntry( final Log log, final String id, final HttpRoute route, final OperatedClientConnection conn, final long timeToLive, final TimeUnit tunit) { super(id, route, conn, timeToLive, tunit); this.log = log; this.tracker = new RouteTracker(route); } @Override public boolean isExpired(final long now) { final boolean expired = super.isExpired(now); if (expired && this.log.isDebugEnabled()) { this.log.debug("Connection " + this + " expired @ " + new Date(getExpiry())); } return expired; } RouteTracker getTracker() { return this.tracker; } HttpRoute getPlannedRoute() { return getRoute(); } HttpRoute getEffectiveRoute() { return this.tracker.toRoute(); } @Override public boolean isClosed() { final OperatedClientConnection conn = getConnection(); return !conn.isOpen(); } @Override public void close() { final OperatedClientConnection conn = getConnection(); try { conn.close(); } catch (final IOException ex) { this.log.debug("I/O error closing connection", ex); } } }
public final class RouteTracker implements RouteInfo, Cloneable { /** The target host to connect to. */ private final HttpHost targetHost; /** * The local address to connect from. * <code>null</code> indicates that the default should be used. */ private final InetAddress localAddress; // the attributes above are fixed at construction time // now follow attributes that indicate the established route /** Whether the first hop of the route is established. */ private boolean connected; /** The proxy chain, if any. */ private HttpHost[] proxyChain; /** Whether the the route is tunnelled end-to-end through proxies. */ private TunnelType tunnelled; /** Whether the route is layered over a tunnel. */ private LayerType layered; /** Whether the route is secure. */ private boolean secure; /** * Creates a new route tracker. * The target and origin need to be specified at creation time. * * @param target the host to which to route * @param local the local address to route from, or * <code>null</code> for the default */ public RouteTracker(final HttpHost target, final InetAddress local) { Args.notNull(target, "Target host"); this.targetHost = target; this.localAddress = local; this.tunnelled = TunnelType.PLAIN; this.layered = LayerType.PLAIN; }
相关推荐
- 通过查看源码,可以了解内部的工作原理,比如连接池管理、线程安全、错误处理等。 - 可以学习如何优化网络请求,提高性能和稳定性。 - 对于自定义行为或扩展功能,理解源码可以帮助进行定制化开发。 总之,...
HttpClient的`PoolingHttpClientConnectionManager`实现了连接池,可以有效地复用TCP连接,提高性能。`CloseableHttpClient`接口提供了关闭连接的方法,以释放系统资源。 HttpClient还提供了多种认证机制。例如,`...
《连接池实现原理及效率测试》 连接池是数据库应用中的一个重要概念,它在系统设计中扮演着提高性能、优化资源利用的关键角色。本文将深入探讨连接池的实现原理,并通过实际测试分析其效率。 首先,我们需要理解...
1. `HttpClient`:客户端的核心,负责管理请求执行策略、连接池和重试机制等。 2. `HttpConnectionManager`:管理 HTTP 连接,包括建立、复用和关闭连接。 3. `HttpRequestExecutor`:执行 HTTP 请求,处理响应。 4....
HTTPClient4允许高度定制,通过`HttpClientBuilder`可以设置连接超时、重试策略、连接池大小等参数。此外,还可以通过`RequestConfig`对象配置单个请求的行为。 10. **性能优化**: 为了提高性能,HTTPClient4...
在Spring Boot应用中,连接池是管理数据库连接的关键组件,它能提高数据库操作的效率和应用程序的性能。本文将深入探讨如何使用注解配置在Spring Boot中设置连接池。 首先,Spring Boot默认集成了多种数据库连接池...
《HttpClient 4.0.3源代码解析》 HttpClient是一个由Apache基金会开发的开源HTTP客户端API,广泛应用于Java编程环境中,用于实现与HTTP服务器的通信。版本4.0.3是HttpClient的一个稳定版本,提供了丰富的功能和改进...
对于源码分析,`httpcomponents-client-4.5.zip`包含了HttpClient 4.5的完整源代码,开发者可以通过阅读源码来更深入理解其工作原理,例如: - 如何配置和管理连接池。 - 请求和响应的生命周期以及处理流程。 - 如何...
HttpClient使用连接池管理HTTP连接,这有助于提高性能。同时,需要注意HttpClient不是线程安全的,因此在多线程环境中,每个线程应有自己的HttpClient实例。 6. **处理重定向**: HttpClient默认会自动处理重定向...
HTTPClient库提供了丰富的功能,包括发起GET、POST、PUT、DELETE等HTTP方法的请求,支持Cookie管理、重定向处理、HTTP连接池、身份验证以及各种编码和解码等。这使得开发者可以轻松地构建网络应用程序,尤其是对于...
HttpClient提供了一套连接管理机制,包括连接池、连接复用和超时管理。理解这些机制对于优化性能和处理并发请求至关重要。 5. **进度和速率统计** HttpClient本身并不直接提供进度和速率统计功能,但开发者可以...
HttpClient是Apache基金会开发...通过深入学习HttpClient 4.4.1的源代码,开发者可以更好地理解和控制HTTP通信过程,从而编写出高效、可靠的网络应用。同时,这也是一个学习网络编程、HTTP协议和Java并发处理的好材料。
HttpClient还提供了`PoolingHttpClientConnectionManager`,用于管理连接池,提高性能。此外,`HttpRequestRetryHandler`和`RedirectStrategy`等接口允许我们自定义重试策略和重定向处理。 在处理响应时,可以使用`...
描述中提到的“剥离出HttpClient代码,用来做网页爬虫亦可”,这意味着HttpClient的源码不仅适用于常规的网络请求,也可以用于网页爬虫项目。网页爬虫通常需要模拟浏览器行为,频繁地发送请求并解析返回的HTML内容。...
通过阅读和研究源代码,开发者可以深入理解如何在Java中构建一个高效的HTTP客户端,并且可以借鉴其中的设计模式和最佳实践。同时,`commons-httpclient`也常被用作其他库的基础,比如在早期的Spring框架中,就曾经...
- 连接池:HttpClient支持连接池,可以复用已建立的TCP连接,提高性能。可以通过`PoolingHttpClientConnectionManager`管理连接池。 - 设置连接超时:使用`RequestConfig`配置请求的连接超时、Socket超时和重试...
HttpClient 4.5的源码分析可以帮助我们深入理解其内部工作原理,包括连接池管理、线程安全、异步操作、SSL/TLS配置、代理设置、超时控制等方面。源码中的关键类包括`CloseableHttpClient`、`HttpGet`、`HttpPost`、`...
通过阅读源码,我们可以学习如何实现HTTP客户端的功能,如设置请求头、处理重定向、管理连接池等。 2. **设计模式**:HttpClient的实现运用了多种设计模式,例如工厂模式(用于创建HTTP请求对象)、策略模式(用于...
3. 源代码:通过阅读源代码,开发者可以理解HttpClient内部的工作机制,以及如何实现自定义功能。 六、最佳实践 1. 使用连接池:HttpClient支持连接池,可提高并发性能并减少资源消耗。 2. 正确处理异常:对可能...
HTTPClient是Apache软件基金会的一个开放源代码项目,主要用于提供HTTP协议的客户端编程接口。这个项目的最新版本是4.5.5,它包含了丰富的功能和优化,以满足开发人员在处理HTTP请求时的需求。本篇文章将深入探讨...