Java Apache HTTPClient Tutorial 深度学习(二)

来源:互联网 发布:tower mac 注册码 编辑:程序博客网 时间:2024/06/04 20:10
Apache HTTPClient Tutorial 深度学习(二) 对于HTTP连接的管理


2.1. Connection persistence(连接持久性)

        从一个主机到另一个主机之间建立连接的过程相当复杂并且涉及到两个端点之间的多个包交换,这可能相当耗时的开销。特别是对于小型HTTP消息,握手连接可能是很重要的如果可以实现一个重新使用开放连接来执行多个请求,那么就会有更高的数据吞吐量。
        HTTP/1.1 声明HTTP连接可以在每次默认的多个请求中被重用。HTTP / 1.0兼容的端点还可以使用一种机制来显式地表达它们的首选项连接到多个请求,并使用它。HTTP代理还可以保持空闲连接的存在在特定的时间段内,对于后续请求,需要连接到相同的目标主机。保持连接的能力通常被称为连接持。HttpClient完全支持连接的持久性。


2.2. HTTP connection routing(HTTP连接路由)

        HttpClient 可以直接或通过路由建立到目标主机的连接可能涉及多个中间连接,也称为跃点。HttpClient 区别一条路线连接到一条平坦、隧道和分层的道路。
多中间代理的使用与目标主机的隧道连接被称为代理链接。
        普通路由是通过连接到目标或第一个和唯一的代理来建立的。挖过的路线通过连接到第一个和隧道,通过连接到目标的一系列代理来建立。路线没有代理,就不能被隧道掘进。分层路由是通过在一个协议之上建立一个协议来建立的。现有的连接。协议只能通过隧道到达目标,或者直接连接到目标上。没有代理。


2.2.1. Route computation(路由估算)

        RouteInfo接口表示关于目标主机的确定路由的信息一个或多个中间步骤或跃点。HttpRouteRouteInfo的具体实现,不能改变的(是不可变的)。HttpTracker是一个可变的RouteInfo实现在内部,HttpClient可以跟踪剩余的跳线到最终的路由目标。HttpTracker可以在成功执行下一跳到路由目标之后。HttpRouteDirector一个助手类,可用于计算路由中的下一个步骤。这个类是在内部使用的HttpClient
    HttpRoutePlanner是一个接口,它表示一个策略,用于计算给定目标的完整路由基于执行上下文。HttpClient附带两个默认的http自豪计划实现。SystemDefaultRoutePlanner基于java.net.ProxySelector。默认情况下,它会接收到JVM的代理设置,要么来自系统属性,要么来自运行应用程序的浏览器。DefaultProxyRoutePlanner实现不使用任何Java系统属性,也没有任何系统或浏览器代理设置。它总是通过相同的默认代理计算路由。

2.2.2. Secure HTTP connections(安全的HTTP连接)

        如果在两个连接之间传输的信息,HTTP连接可以被认为是安全的端点不能被未经授权的第三方读取或篡改。SSL / TLS协议是用于确保HTTP传输安全性的最广泛使用的技术。然而,其他加密技术也可以被运用。通常,HTTP传输是通过ssl/tls加密的连接。

2.3. HTTP connection managers(HTTP连接管理)

        HTTP连接是复杂的、有状态的、线程不安全的对象,需要正确地管理这些对象正确的函数。HTTP连接只能一次被一个执行线程使用。HttpClient使用一个特殊的实体来管理访问HTTP连接管理器的HTTP连接管理器和由HttpClientConnectionManager接口。HTTP连接的目的管理器将作为新的HTTP连接的工厂,管理持久性的生命周期连接和同步连接到持久连接,确保只有一个线程可以一次访问连接。内部HTTP连接管理器与实例一起工作ManagedHttpClientConnection作为代表一个真正的连接管理连接状态并控制执行的输入/输出操作。如果一个托管连接被释放或被显式关闭通过它的使用者,底层连接从代理中分离,并返回到经理。尽管服务使用者仍然持有代理实例的引用,但它已不再能够执行任何的输入/输出操作或改变真实连接的状态无意中。

这是一个从连接管理器获取连接的例子:



连接请求可以通过调用ConnectionRequest cancel()来提前终止。必要的。这将解开ConnectionRequest get()方法中阻塞的线程。

2.3.2. Simple connection manager

    BasicHttpClientConnectionManager是一个简单的连接管理器,保持只有一个一次连接。尽管这个类是线程安全的,但它应该被一个执行线程使用只有。BasicHttpClientConnectionManager将为后续努力重用连接使用相同路径的请求。但是,它将关闭现有的连接并重新打开它给定路由,如果持久连接的路由与连接请求的路径不匹配。如果连接已经被分配了,然后是java.lang。IllegalStateException抛出。该连接管理器实现应该在EJB容器内使用。

2.3.3. Pooling connection manager(连接池管理)

    PoolingHttpClientConnectionManager是一个更复杂的实现管理池客户端连接,并且能够从多个执行线程中服务连接请求。连接在每个路由基础上被汇集起来。对经理已经拥有的一条路线的请求
池中可用的持久连接将通过从池中租赁连接来服务而不是建立一个全新的联系。
    PoolingHttpClientConnectionManager保持最大限度的连接每个路线基础和总计。在默认情况下,该实现将创建不超过2个并发连接每个给定的路由,总共不超过20个连接。对于许多实际应用程序来说,这些限制可能会被证明过于约束,特别是当他们使用HTTP作为他们的服务的传输协议时。

这个例子展示了如何调整连接池参数:




2.3.4. Connection manager shutdown(释放连接)

当HttpClient实例不再需要并且即将退出时,关闭它是很重要的关闭它的连接管理器以确保管理器的所有连接都被关闭这些连接分配的系统资源被释放。



2.4. Multithreaded request execution

        当配备一个池PoolingClientConnectionManager等连接管理器,HttpClient可以被用来同时执行多个请求,同时使用多个线程执行。
        根据其配置PoolingClientConnectionManager将分配连接。如果所有一个给定路由的连接已经被租借,一个连接的请求将被阻塞。直到连接被释放到池中。可以确保连接管理器不会通过设置http.connmanager.超时,在连接请求操作中无限期地阻塞。一个积极的价值。如果在给定的时间段内不能对连接请求进行服务就会抛出onnectionPoolTimeoutException。




虽然HttpClient实例是线程安全的,并且可以在多个执行线程之间共享,强烈建议每个线程维护自己专用的HttpContext实例。



2.5. Connection eviction policy

        经典阻塞输入/输出模型的主要缺点之一是网络套接字可以对其进行响应只有在一个输入/输出操作中阻塞时才会发生。当一个连接被释放到经理的时候,它可以被保存,但是它不能监控套接字的状态并对任何输入/输出事件作出反应。如果连接在服务器端关闭,则客户端连接无法检测到更改在连接状态(并在结束时关闭套接字)。
        HttpClient试图通过测试连接是否“过时”来缓解这个问题,这是不存在的因为它在服务器端关闭,在使用连接执行之前一个HTTP请求。过期的连接检查不是100%可靠的。唯一可行的解决方案对于空闲连接来说,每个套接字模型都不涉及一个线程,这是一个专用的监视器线程用来清除由于长时间不活动而被认为过期的连接。监控线程可以周期性地调用ClientConnectionManager关闭补偿连接()方法关闭所有过期连接,并将关闭连接从池中清除。它还可以可选地调用ClientConnectionManager近端()方法来关闭所有连接在给定的一段时间内,这些都是闲置的。




2.6. Connection keep alive strategy

        HTTP规范没有指定持久连接可能存在多长时间,应该保持多长时间活着。一些HTTP服务器使用非标准的保持-活着的头来与客户端通信在几秒钟内,他们打算将连接保持在服务器端。HttpClient使如果有的话,可以使用这些信息。如果没有在响应中出现keep活着的头部,那么HttpClient就会出现假设连接可以无限地存活。但是,通常使用的许多HTTP服务器在特定的一段时间不活动之后,配置为减少持久连接,以便保存系统资源,经常不通知客户。如果默认策略是过于乐观的人可能会想要提供一种自定义的维持生命的策略。



2.7. Connection socket factories

        HTTP连接在内部使用java.net.socket对象来处理数据的传输。过线。但是,它们依赖于ConnectionSocketFactory接口来创建、初始化和连接的套接字。这使HttpClient的用户能够提供特定于应用程序的套接字在运行时初始化代码。PlainConnectionSocketFactory是默认为创建和工厂初始化(加密)套接字。
        创建套接字的过程和将其连接到主机的过程是解耦的,所以这个套接字在连接操作中被阻塞时,可以关闭。



2.7.1. Secure socket layering

    LayeredConnectionSocketFactory ConnectionSocketFactory接口的一个扩展。分层套接字工厂能够在现有的普通插座上创建套接字。套接字分层主要用于通过代理创建安全的套接字。HttpClient附带实现ssl/tls分层的SSLSocketFactory。请注意,HttpClient不使用任何定制加密功能。它完全依赖于标准的Java加密(JCE)和安全套接字(JSEE)扩展。

2.7.2. Integration with connection manager

自定义连接套接字工厂可以与特定的协议方案相关联,如HTTP或者HTTPS,然后用来创建一个自定义连接管理器。



2.7.3. SSL/TLS customization

        HttpClient利用SSLConnectionSocketFactory创建SSL连接。SSLConnectionSocketFactory允许高度的定制。它可以举一个例子作为一个参数使用javax.ssl.sslcontext,并使用它创建自定义配置的SSL连接。



        定制SSLConnectionSocketFactory意味着一定程度的熟悉ssl/tls协议的概念,一个详细的解释,它超出了范围对于本文档。请参阅Java安全套接字扩展(JSSE)引用指南[http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html详细描述javax.net.ssl.sslcontext和相关工具。

2.7.4. Hostname verification

        除了在SSL上执行的信任验证和客户端身份验证之外TLS协议级别,HttpClient可以选择性地验证目标主机名是否与此匹配存储在服务器x中的名称。当连接建立后,证书。这种验证可以为服务器信任材料的真实性提供额外的保证。javax.net.ssl.HostnameVerifier接口代表主机名验证的策略。HttpClient附带两javax.net.ssl.HostnameVerifier实现。重要的是:主机名验证不应与SSL信任验证混淆。

  • DefaultHostnameVerifier:HttpClient  使用的默认实现是符合RFC 2818。主机名必须匹配由该名称指定的任何其他名称证书,或者在没有其他名称的情况下,给出证书主题的最特定的CN。通配符可以在CN中出现,也可以在任何主项中出现。
  • NoopHostnameVerifier:  这个主机名验证器实际上是将主机名验证关闭。接受任何SSL会话是有效的,并匹配目标主机。

在默认情况下,HttpClient使用DefaultHostnameVerifier实现。可以指定一个如果需要,不同的主机名验证器实现



        在版本4.4中,HttpClient使用Mozilla基金会友好维护的公共后缀列表确保SSL证书中的通配符不能被误用用于应用到多个域通用顶级域名。HttpClient将在发布时检索到的列表副本。最新修订版本的列表可以在https://publicsuffix.org/list/找到[https://publicsuffix.org/list/effective_tld_names.dat]。可以对列表进行本地复制并下载该列表,这是非常明智的。从它最初的位置开始一天不超过一次。



可以使用空matcher来禁用对公共列表的验证。



2.8. HttpClient proxy configuration

        尽管HttpClient知道复杂的路由方案和代理链接,但它只支持简单的直接或单跳的代理连接。
        要让HttpClient通过代理连接到目标主机,最简单的方法是设置缺省值代理参数:



您还可以指示HttpClient使用标准的JRE代理选择器来获取代理信息:



或者,您可以提供定制的RoutePlanner实现来完成一个完整的任务对HTTP路由计算过程的控制:



About Me:

  • Github地址:https://github.com/noseparte 
  • Email: noseparte@aliyun.com     有java与hadoop相关的技术问题,可以发私信与我交流。
  • NPM地址: https://www.npmjs.com/~noseparte
  • WebSite: http://www.noseparte.com/  Copyright © 2017 noseparte