Httpclient核心架构设计

2018-10-07  本文已影响12人  编码前线

Http简介

通常,我们使用IE或者safari来访问互联网上的内容,只需要输入资源地址,浏览器便会呈现给你想要的内容。这一切的背后,都是迄今为止在计算机领域最成功的协议–http协议。

Http协议分为请求和响应,客户端建立连接,接着发送请求,服务端接受并处理请求,再发送应答,再由客户端接受并处理应答。浏览器是最最常见的一种客户端,它将用户的交互行为作为http请求发送,并接受服务端的应答,再将应答内容展示,一般应答都是html类型的超文本。

浏览器显然不是唯一的客户端,理论上任何遵循了http规范都可作为客户端。在程序里也可以通过java api实现简单的客户端–使用HttpURLConnection发送http请求,并解析应答。假设应答是个html或者json,则只需要基于双方约定的格式进行解析就能得到所需结果。

Http, tcp/ip和socket区别

Tcp/ip是传输层协议,而http则是建立在它之上的上层应用协议。Http聚焦在数据规范层面,tcp/ip则主要解决数据传输层面。如果没有规范的应用协议,数据能从网络里的A节点传到B节点,但却无法有效识别,建立在tcp/ip上的应用协议很多,像rpc,ftp等,反过来不管应用协议有多强大最终都需要依靠传输层协议进行数据传输。
Socket则是tcp/ip的一个编程实现,在程序里http请求(连接)最终一定需要绑定到一个具体的socket连接进行上行和下行传输。

整体架构

对于简单应用,HttpURLConnection完全可以满足。但是对于1)系统复杂度高,2)性能要求高,3)可靠性要求也高的应用,则需要一个更强大的组件。

image

Httpclient里接受者称为为route,并为每个route池化若干连接。Client通过socket发送请求以及接受应答,在发送请求前和接收应答后都会经由interceptor进行链式处理,在httpclient里这些interceptor被称为HttpProcessor,负责处理诸如设置报文头,报文体,编码格式等以及解析报文头,报文体,解码格式等http规范文本格式范畴内的事情。

HttpClient静态结构

image image

connection被创建出来后处于闲置状态,由连接池管理,被lease后会校验是否是open状态,不是的话会进行connect,connect的过程就是将http请求(连接)绑定到socket的过程。同时连接也会因为心跳或者过期等原因被close变成stale状态,直至被下一次get到时或者连接满时被清理出去。

同时连接池还能对连接进行限流–全局和单route连接数。Connection manager封装了对连接池的具体操作,比如向连接池租用和归还连接;还提供了基于不同schema(主要是http和https)创建不同的socket连接(ssl和plain)并且将http请求(连接)绑定到socket的能力,等等。
4. HttpRoutePlanner用来创建HttpRoute。后者代表客户端request的对端服务器,主要包含rout的host以及proxy信息。
5. ClientExecChain代表一次完整的调用执行过程,它是一个包装类,类似于java io类,每个包装类完成一个特定的功能,多层嵌套完成一个系统性的功能,比如处理协议范畴的例如cookie、报文解析等,又比如处理自动重试的,等等。

连接池

image

执行链

image
InterruptedIOException
UnknownHostException
ConnectException
SSLException

最后注意一点,以上的这些exec只有MainClientExec和ProtocolExec是默认开启的,其他的都需要通过HttpClientBuilder设置参数开启,具体可以参考文档或者源码。

调优方向

了解了架构原理后,就可以着手在3个方向进行调优:
1. 连接数,通过设立全局最大连接数和单route连接数,增加吞吐能力。用户可通过HttpClientBuilder#maxConnTotal和#maxConnPerRoute分别设置。
2. 获取连接的超时时间,调小超时时间能够有效提高响应速度并且降低积压请求量,但相应的也会增加请求失败的几率。用户可以通过RequestConfig的connectionRequestTimeout进行设置。
3. 建立连接和route响应的超时时间,调小能够有效的降低bad request对连接的占用,留给质量更好的请求,有效提高系统提高吞吐能力及响应速度。否则有可能在峰值期被慢请求占满连接池,导致系统瘫痪。两者分别可通过RequestConfig#connectionTimeout和socketTimeout进行设置。
4. 开启BackoffStrategyExec,对状况差的route进行降级处理,将连接让给其他route

上一篇 下一篇

猜你喜欢

热点阅读