最近线上出现了一些超时问题的日志,这让我产生了深入探究的欲望。于是,我决定聚焦于HttpClient中的三种超时时间设置。这些设置可以在RequestConfig配置类中定义,它们分别是connectionRequestTimeout、connectTimeout和socketTimeout。我将针对这些参数进行详细的探讨。
一、实验准备
为了更好地理解这些超时参数的实际表现,我制定了以下实验方案:
我准备了一份服务端代码,其中包括一个controller。接着,我准备了一个测试类作为客户端,用于发送请求到服务端。
二、实验过程与结果分析
1. connectTimeout验证
connectTimeout指的是客户端与服务端建立连接的超时时间,即三次握手阶段的超时。为了验证这一点,我调整了客户端的请求代码,将请求端口号设置为错误值,以模拟三次握手不成功的情况。实验结果显示出现了connectTimeout报错。通过调整客户端代码中的setConnectTimeout()的值,我发现当该值设置为超过2000ms时,似乎就失去了作用。
2. socketTimeout验证
socketTimeout是在客户端与服务端建立连接后,两者间数据包传输的超时时间。这个超时时间是针对单次数据包的,而非整个数据传输过程的超时。为了验证这一点,我调整了服务端Controller的代码,使其多次发送数据并在每次发送后短暂休眠。我也调整了客户端的socketTimeout值。当该值设置为999ms时,出现了socket time out报错。而当我们将socketTimeout值调大时,错误消失,可以正常获取完整的数据。这验证了我们的猜想:socketTimeout是针对单个数据包的超时时间,而不是整个数据传输过程的超时时间。
3. connectionRequestTimeout验证
connectionRequestTimeout是客户端从连接池中获取连接的超时时间。为了验证这一点,我调整了客户端代码以指定线程池大小,使连接池满载,从而导致无法获取连接。实验结果显示出现了“Timeout waiting for connection from pool”的错误。这验证了我们的猜想:当连接池中的连接被占满且等待时间过长时,就会出现该错误。
通过上述实验,我对connectionRequestTimeout、connectTimeout和socketTimeout三个超时时间有了更深入的理解。这对于我们未来在遇到线上异常报错时,能迅速定位问题原因提供了极大的帮助。例如,如果是ConnectTimeout异常,那么很可能是由于服务端网络问题、服务端关机或服务端端口问题导致的;如果是SocketTimeout异常,则可能是由于服务端忙碌、线程数已满或服务端性能受限等原因造成的。至于connectionRequestTimeout异常,目前我还未在实际环境中遇到过此类异常。