对于HTTP调用,虽然应用层走的是HTTP协议,但网络层面始终是TCP/IP协议。TCP/IP是面向连接的协议,在传输数据之前需要建立连接。几乎所有的网络框架都会提供这么两个超时参数:
连接超时参数ConnectTimeout,让用户配置建连阶段的最长等待时间;读取超时参数ReadTimeout,用来控制从Socket上读取数据的最长等待时间。连接超时参数和连接超时的误区有这么两个:
连接超时配置得特别长,比如60秒。一般来说,TCP三次握手建立连接需要的时间非常短,通常在毫秒级最多到秒级,不可能需要十几秒甚至几十秒。如果很久都无法建连,很可能是网络或防火墙配置的问题。这种情况下,如果几秒连接不上,那么可能永远也连接不上。因此,设置特别长的连接超时意义不大,将其配置得短一些(比如1~5秒)即可。如果是纯内网调用的话,这个参数可以设置得更短,在下游服务离线无法连接的时候,可以快速失败。排查连接超时问题,却没理清连的是哪里。通常情况下,我们的服务会有多个节点,如果别的客户端通过客户端负载均衡技术来连接服务端,那么客户端和服务端会直接建立连接,此时出现连接超时大概率是服务端的问题;而如果服务端通过类似Nginx的反向代理来负载均衡,客户端连接的其实是Nginx,而不是服务端,此时出现连接超时应该排查Nginx读取超时误区:
读取时间服务端处理和返回的时间 ,但传输快。可以认为绝大部分的时间,是服务端处理业务逻辑的时间。 发生了读取超时,网络层面无法区分是服务端没有把数据返回给客户端,还是数据在网络上耗时较久或丢包。但,因为TCP是先建立连接后传输数据,对于网络情况不是特别糟糕的服务调用,通常可以认为出现连接超时是网络问题或服务不在线,而出现读取超时是服务处理超时。确切地说,读取超时指的是,向Socket写入数据后,我们等到Socket返回数据的超时时间,其中包含的时间或者 说绝大部分的时间,是服务端处理业务逻辑的时间。
认为超时时间越长任务接口成功率就越高,将读取超时参数配置得太长。 进行HTTP请求一般是需要获得结果的,属于同步调用。如果超时时间很长,在等待服务端返回数据的同时,客户端线程(通常是Tomcat线程)也在等待,当下游服务出现大量超时的时候,程序可能也会受到拖累创建大量线程,最终崩溃。
对定时任务或异步任务来说,读取超时配置得长些问题不大。但面向用户响应的请求或是微服务短平快的同步接口调用,并发量一般较大,我 们应该设置一个较短的读取超时时间,以防止被下游服务拖慢,通常不会设置超过30秒的读取超时。 你可能会说,如果把读取超时设置为2秒,服务端接口需要3秒,岂不是永远都拿不到执行结果了?的确是这样,因此设置读取超时一定要根据 实际情况,过长可能会让下游抖动影响到自己,过短又可能影响成功率。甚至,有些时候我们还要根据下游服务的SLA,为不同的服务端接口 设置不同的客户端读取超时。