关于httpclient的各种超时时间

3,179 阅读2分钟

就Java apache httpclient中的一些超时时间做一些分析,按照代码执行的先后顺序,会经历以下几种超时。

1 ConnectionRequestTimeout

从线程池获取连接的超时时间,跟其他池化的资源方式一样,可以从连接池中直接获取连接,减少创建连接的时间。一般发生在高并发的情况下,解决的办法就是增加线程池的大小,因为都是内存中的操作,增大获取连接的超时时间意义不大,只会增加上层逻辑的耗时。

2 ConnectTimeout

与目标地址建立连接的超时时间,包含建立http的tcp三次握手时间。比如在连接一个不存在的地址时,如果ConnectTimeout设置成1000ms,那么在1000ms后就会报:org.apache.commons.httpclient.ConnectTimeoutException:The host did not accept the connection within timeout of 1000 ms 。

建立连接的时间在正常网络情况下,需要耗费的时间都非常的少,除非是前端请求后端这种网络不是特别稳定的状态。如果是单纯的后端内部间的网络交互,耗时可能不到几毫秒。如果几毫秒都无法建立连接的话,可能服务端无响应(可能压力过大无法及时建立连接)或者网络出了问题。

3 SocketTimeout

读取数据超时时间,在请求一个地址后,有些接口内部可能要读写数据库等之类的操作,需要耗费一定的时长,但为了避免长时间一直等待,就需要设置一个读取数据的超时时间,在这个时间内还没有返回数据的话,就中断请求。比如一个接口内部处理可能需要耗费3s,如果我们将SocketTimeout设置成1s的话,那么1s后程序就会抛出异常:java.net.SocketTimeoutException:Read timed out 。

在内部服务之间可能最需要关注的就是这个SocketTimeout了,因为不同的接口响应时间各不相同,设置的太短,可能服务端还没有处理完成就导致了Read timed out,设置的太长会降低自身服务吞度量或者进而影响上游服务的处理速度。

所以在使用httpclient的时候,除了接口必要的参数外,其他的超时时间都可以统一在初始化的时候设置成固定的值,但SocketTimeout可以针对不同的请求设置不同的时间,这样有助于提高服务的响应时间(快速失败在底层服务不可用的时候未尝不是个好的选择)