连接服务器超时是什么意思(连接服务器超时如何解决)

今天我们就和朋友们聊聊连接服务器超时的问题。以下关于如何解决服务器连接超时的意见希望能帮助您找到您想要的百科全书。

对于云上的用户来说,处理业务日志的超时问题往往比较困难,因为1)问题可能出在云基础设施层,也可能出在业务软件层,而且排查的范围很广;2)此类问题通常不可重现且难以在现场发现。在本文中,我们将分析如何识别并排除此类问题的根本原因。

连接服务器超时是什么意思(连接服务器超时如何解决)

业务超时!=网络丢包

由于业务形态、软件实现语言和框架不同,业务日志中打印的信息可能会有所不同,比如以下关键字:

'socketTimeOut'、'读取超时'、'请求超时'等。

从形式上看,它们都属于网络超时的范畴,但是需要明确一个概念:这类问题是因为请求超过了设定的超时时间而出现的。该设置可能来自客户端、服务器或网络中间节点。这是直接原因。网络丢包可能会导致超时,但这不是充分条件。服务超时与网络丢包的关系总结如下:

网络丢包可能会导致服务超时,但服务超时的原因不一定是丢包。

明确了这个因果关系之后,我们再来看看如何分析业务超时。如果我们武断地将业务超时等同于网络抖动、丢包,那么排查分析过程就会完全错过业务软件层本身的原因,很容易陷入困境。

本文将从云基础设施层和业务软件层来分析业务超时。一般来说,基础设施层面的丢包原因比较容易排查。阿里云底层监控完善。根据业务日志错误报告对应时间段,从监控数据可以判断是否存在基础设施网络问题。业务层的超时通常是软件层面的设置,与软件实现和业务形态有关。这种超时通常更难以排除故障。

为什么网络丢包会导致服务超时?

网络抖动可能会导致服务超时。主要原因是网络抖动会造成不同程度的延迟。本文以大多数互联网应用中已使用的TCP作为介绍。丢包实际上并不会影响数据传输的完整性,因为TCP协议本身就经过了精心设计,可以处理丢包、乱序等异常情况。并且所有的重传处理都是在内核TCP协议栈中完成的,操作系统用户空间进程实际上是感知不到这个处理的。丢包的唯一副作用是增加延迟。如果这个延迟足够长,达到应用进程设置的某个Timeout,那么业务应用端就会出现业务超时。

丢包时是否超时取决于应用进程的Timeout设置。例如,数据传输过程中仅丢失一个TCP数据包,导致200ms后超时重传:

如果应用程序设置的Timeout为100ms,则TCP协议栈没有机会重传,应用程序会考虑超时并关闭连接;如果应用程序设置的Timeout为500ms,TCP协议栈就会完成重传,这个过程对应用程序进程是透明的。应用程序的唯一感知是此数据包交互的处理时间比基线处理时间长200毫秒。对于时间不太敏感的应用程序来说,这种影响很小。

延迟有多大?

设置应用进程Timeout时间时有没有什么量化值可以参考?虽然TCP中的RTT/RTO是动态变化的,但是TCP丢包的影响是可以定量概括的。

丢包引起的延迟主要分为以下两类:

TCP连接建立超时。如果网络抖动不幸丢失了TCP的第一个连接建立SYN消息,对于不太旧的内核版本,客户端将在1秒后再次重传SYN消息(在RFC2988bis-02草案中定义)发起连接建立。1秒对于内网环境来说已经很长了。对于阿里云某个地域的机房来说,正常的RTT在个位数毫秒级别。如果1秒内没有丢包,就足以完成数百个数据报的交互。TCP中间丢包。TCP协议有两种处理数据包丢失的机制:快速重传和超时重传。快重传通常速度更快,与RTT相关,没有量化价值。重传超时(RTO,RetrasmissionTimeout)也和RTT有关,但是Linux中定义的RTO最小值是,TCP_RTO_MIN=200ms。因此,在RTT比较小的网络环境下,即使RTT小于1ms,TCP超时重传的最小RTO值也只能是200ms。这种丢包造成的延迟比较小。

除了丢包之外,另一种常见的延迟是TCPDelayedACK造成的延迟。这与协议设计有关,与丢包无关。这里总结为延迟定量部分。Nagle算法在交互数据流的场景下更容易触发。Linux中定义的DelayedACKTCP_DELACK_MIN的最小值为40ms。

所以综上,有以下几个量化时间可供参考:

40ms,交互数据流启用TCPDelayedACKNagle算法场景下的最小延迟值。200ms,在RTT较小的正常网络环境下,TCP丢包和超时重传的最小值。1s,较新内核版本中TCP建立的第一个SYN包丢失时的重传时间,RFC2988bis中定义的初始RTO值TCP_TIMEOUT_INIT。3s,老内核版本中TCP建立的第一个SYN包丢失时的重传时间,RFC1122中定义的RTO初始值TCP_TIMEOUT_INIT。

云基础设施网络丢包

基础设施网络丢包的原因可能有很多,主要概括为以下三类:

云基础设施网络抖动

ECS/RDS等所在的网络链路、物理网络设备、主机虚拟化网络等都可能存在软硬件问题。云基础设施具有完全冗余,保证出现问题时快速隔离、切换和恢复。

现象:由于存在网络冗余设备且能够快速恢复,此类问题通常表现为单时间点的网络抖动,一般为秒级。抖动的具体现象是该期间新的连接失败,已建立的连接中断,在业务中可能表现为超时。

影响区域:通常网络设备连接的主机较多,影响区域通常比较大,比如同时影响多个ECS和RDS之间的连接。

云产品限速丢包

很多网络云产品在销售时都会附带规格和带宽选项,例如ECS、SLB、NAT网关等。当云产品的流量或连接数超过规格或带宽限制时,也可能会出现丢包的情况。这种丢包并非云厂商的过错,而是实际业务流量规模与云产品规格选择存在偏差造成的。这个问题往往可以从云产品提供的监控中看出。

现象:当流量或连接数超过规格时,流量或连接会被丢弃。问题可能会间歇性地或连续性地发生,并且更有可能发生在网络流量的高峰期。

影响区域:通常仅影响单个实例。但对于NAT网关进行SNAT的场景,可能会影响SNAT后的多个实例。

运营商网络问题

在公网场景中,客户端和服务器之间的报文交互往往会经过多个AS(自治系统)。如果运营商的中间链路出现问题,往往会导致端到端的丢包。

现象:使用双向mtr,您可以看到数据包在链路中间的某个跃点开始丢失。

影响区域:影响区域可能较大,可能会影响经过某条AS链路的报文交互。但单个用户看到的影响通常仅针对特定实例。

应用程序设置的Timeout导致的超时

以上分析分析了几种基础设施中因异常或限速导致丢包导致应用超时的几种情况。一般来说,只要能找到丢包点,基本上就能找到根本原因。但在某些情况下,各种网络监控显示并没有丢包的迹象。这时候就需要继续从应用端进行排查。由于应用的形式多种多样,这里举两个典型的例子来说明为什么在没有网络丢包的情况下,业务日志也会出现超时的情况。

ECS云主机访问第三方API超时示例

问题现象

用户云上的ECS服务器需要通过HTTP协议访问第三方服务器的API,但发现业务日志中不时出现访问第三方API时“请求超时”的错误。需要找到根本原因。

故障排除思路

根据基本思路,首先通过监控检查ECS实例和链路是否有丢包。发现业务日志中没有出现与超时错误发生时间相匹配的丢包情况。这种情况下,我们只能进一步使用问题再次出现时的抓包来查找。

抓包分析

得到抓包后,可以使用Wireshark的“分析-专家信息”或者下面的表达式来过滤是否有重传。

tcp.分析.重传

结果我们没有看到丢包的情况,这也证明问题不是丢包造成的。如果不是丢包造成的,那为什么会出现问题呢?这时就需要对抓包进行进一步的分析。

我们可以注意到,业务日志中其实有一个“RequestTimeout”这样的关键字,字面意思就是发出的HTTP请求超时。用HTTP协议的话来说,可以翻译为:“HTTP请求已经发送到对端,但对端在一段时间内没有返回完整的响应”。沿着这个思路,我们可以看到消息中是否只有HTTP请求而没有HTTP响应。在Wireshark中,可以使用以下方法过滤没有HTTP响应的HTTP请求:

http.request.method==GET!http.response_in

果然,我们发现了一些这样的HTTP请求。选择其中一个HTTP请求,然后顺着TCP流看整个消息交互过程如下:

根据抓包,你会发现以下内容:

在TCP流中,可以看到一个TCP连接上有两个HTTP请求,因此ECS使用长连接来访问第三方API。第一个HTTPGET请求(包号735)在65毫秒(包号778)后返回。第二个HTTPGET请求(包号780)没有返回相应的HTTP响应(我们根据这个条件过滤了数据包)。954号包中,客户端在收到HTTP响应之前主动FINed了TCP连接。这是非常不寻常的行为,是由客户发起的。仔细观察FIN和第二次HTTPGET请求之间的时间间隔,大约为300毫秒。然后检查其他无响应的HTTP流。这个时间间隔大约是300ms。

此时,我们有理由推断ECS服务器在向第三方API发出HTTP请求300ms后主动FIN了TCP连接。这可能是客户端在程序中设置的超时,业务程序可能有自己的超时后重试逻辑。

用户最终确认业务软件中存在超时设置。

问题的结论

1)300ms的超时设置是否合理?

从抓包中可以看出,ECS对端API服务器的RTT约为7ms,推断是同城访问。对于个位数毫秒的RTT来说,300ms的超时实际上是有一定余量的,甚至可能允许超时重传(200ms)。

2)问题的根本原因是什么?

该问题主要是由于对端API服务器处理请求不稳定造成的。有的请求在几十毫秒内就处理完毕并返回,有的则需要300毫秒才处理完毕。这种不稳定可能与API服务器的资源水平和压力有关,但这是一个黑匣子,需要同行分析。

3)解决方案

1最好的解决方案是联系对等API服务器的所有者以查找根本原因并消除它。

2临时解决方案是调整并增加ECS上设置的客户端超时时间。

ECS网络内访问自建Redis超时示例

ECS访问云服务RDS/Cache或者自建数据库/Cache超时是另一类问题。下面以一个ECS内网访问字节Redis超时来说明此类问题。

问题现象

使用ECS上的Redis客户端Jedis访问ECS上自建的Redis服务器,偶尔会出现如下错误:

redis.clients.jedis.exceptions.JedisConnectionException:java.Net.SocketTimeoutException:读取超时

故障排除思路

造成此类问题的一个常见原因是Redis查询速度慢。用户自查了Redis的大键慢查询状态,没有发现特别长的查询。因此,还需要网络层面进一步确认。根据基本思路,首先通过监控检查ECS实例和链路是否有丢包。事实证明,不存在与“读取超时”错误报告时间点相匹配的丢包情况。我们进一步通过问题重复出现时的抓包来找出答案。由于该问题偶尔出现,因此需要在客户端使用tcpdump-C-W参数部署环路抓包。出现问题后,停止循环抓包查看。

抓包分析

拿到抓包后,我们也首先检查是否有丢包和重传的情况。结果没有发现丢包和重传。与前面的示例不同,此示例无法按某些特征过滤数据包。因此,我们只能根据Jedis日志报错的时间点找到对应包的位置,看看是否还有进一步的线索。

根据Jedis日志报错的时间点找到对应的消息,查看消息与TCP流交互的整个过程如下(Jedis客户端为9.20,Redis服务端为20.66):

根据抓包,得出以下结论:

可以看到中间没有重传,网络看起来正常。客户端使用长连接访问服务器,在结束连接之前会包含大量的Redis请求和响应。包号表示服务器端FIN失去了连接,包号表示客户端随后发送了TCPReset。

上面的信息量显然不足以解释为什么会出现“读取超时”错误。客户端最后一次发起的TCPReset可能是一个干扰项。可以看出这个TCPReset是在收到服务器的FIN后发出的。对于正常的TCP四次回收过程来结束连接,客户端在收到服务器的FIN后,还应该向服务器发送FIN来结束连接。然而,TCP有一个Linger选项可以控制这种行为。设置Linger选项后,客户端可以直接返回Reset,这样可以让双方快速关闭这组socket,避免主动关闭并进入TIME_WAIT状态长达60秒。看来是客户端的灵儿设置造成的。我搜索了Jedis代码,发现这个设置确实在Connection.java(下)中找到。这样就可以结束客户端Reset断开TCP连接的原因了。这种行为是合乎逻辑的。

套接字=新套接字();socket.setReuseAddress(true);socket.setKeepAlive(true);//会监听TCP连接是否有效socket.setTcpNoDelay(true);//Socketbuffer是否关闭,保证数据及时送达socket.setSoLinger(true,0);//控制调用close()方法,底层socket立即关闭

接下来看看消息交互中的Redis命令是否正常。通过追踪TCP流,可以看到ASCII形式的数据,如下:

可以看到,客户端发送DEL命令后,又发送了QUIT命令。您可以根据消息进行检查。

客户端发出包中的DEL命令。3.9ms后收到来自Redis服务器的ACK。注意,这只是一个ACK数据包,消息长度为0,表明它不携带任何有效负载数据。在号包中,客户端再次发出QUIT命令。请注意,此包与DEL命令包之间的差异约为200ms。Quit命令用于关闭当前客户端与Redis服务器的连接。一旦所有等待回复(如果有)成功写入客户端,连接将被关闭。包号,即发出QUIT命令161ms后,Redis服务器响应“:1”和“OK”。其中,‘:1’响应DEL命令,‘OK’响应QUIT命令。在号包中,Redis用FIN消息结束了这个TCP长连接。

如上所述,连接被中断的关键点是客户端向Redis服务器发送了QUIT命令。至于为什么发送QUIT,并且在上一条命令发送后200ms没有返回时才发送QUIT,很可能是有超时设置。检查了其他几个TCP流,基本上都是以类似的方式结束了TCP长连接。基本上我们可以得出这样的结论。

这个案例与第一个案例非常相似。不同的是,在抓包中,我们看不到客户端在超时时间后直接FIN连接。相反,它会发送RedisQUIT命令,并最终等到上一个命令执行完毕。关闭连接。与第一种方法相比,这是一种更优雅的方法,前提是Redis中存在QUIT命令,并且Jedis内部化了该操作。这个案例更清楚地说明了特定服务对连接行为的影响。Redis客户端和服务器端的交互需要使用消息来进行反向交互。

总结

本文介绍处理业务日志超时问题需要考虑的两个层面:云基础设施层和业务软件层。相当多的问题可能是由基础设施中的网络数据包丢失引起的。通过网络监控和网络产品云监控来定位丢包点非常重要。注意不要将业务超时等同于丢包;另一类业务软件层超时设置原因发生的超时比例相对较小,但需要进行更广泛的调查,并且不应轻易忽视此类原因引起的超时。

Suggestion可数吗(suggestion可数吗初中)
上一篇 2024-10-13 02:25:32
胸部有疤痕可以当兵吗(胸部有疤痕怎么消除)
下一篇 2024-10-13 02:36:34

相关推荐