生产环境的一个 connect timeout 故障排查

问题描述

有用户反馈在dubbo的应用发布后,过几分钟以后,调用方会出现大量的connectTimeout。当时在服务端容器上进行了抓包,看到在故障期间,客户端发了syn,可是服务端没有任何响应。

分析问题

正常的TCP三次握手:
  • 客户端发送syn给服务端发起握手
  • 服务端收到syn后回复syn+ack
  • 客户端收到syn+ack后,回复ack给服务端,此时客户端上这个链接,进入established

从问题描述看,客户端发的sys包到服务端后直接没响应了,我初步猜想是syn队列满了,经过netstat -s去查看队列的状况:
        
1
2
        
3220 times the listen queue of a socket overflowed
3220 SYNs to LISTEN sockets dropped

syn队列和accept队列

这里先解释下syn队列和accept队列:
上图结合三次握手来讲看
  • 客户端使用connect()向服务端发起链接请求(发送syn包),此时客户端的TCP的状态为 SYN_SENT
  • 服务端在收到SYN包后,将TCP相关信息放到 syn队列中,同时向客户端发送syn+ack。服务端TCP的状态为SYN_RCVD
  • 客户端收到服务端的syn+ack后,向服务端发送ack,此时客户端的TCP的状态为 ESTABLISHED。服务端收到ack确认后,从 syn队列里将 TCP 信息取出,并放到 accept队列中,此时服务端的TCP的状态为 ESTABLISHED
咱们能够大概了解了syn队列和accept队列,那再看上面的问题,overflowed表明accept队列溢出,droped表明syn队列溢出,发现 3220 SYNs to LISTEN sockets dropped,这个就是表明syn队列溢出吗?

overflowed和dropped为何同样多

这里又引出一个问题,能够看到overflowed和dropped居然同样多,翻看内核源码(https://elixir.bootlin.com/linux/v4.14.67/source/net/ipv4/tcp_ipv4.c#L1414)
能够看到overflow的时候,tcp dropped也会增长,也就是dropped必定大于等于overflowed。这样看,overflowed和dropped是同样的,只能说明accept队列溢出了,而syn队列溢出为0(3220-3220)。

进一步分析

可是按照syn队列和accept队列的设计,accept队列满了应该不影响syn响应,即不影响三次握手。带着这个疑问咱们再次翻看了 内核源码:

能够看到在建连的时候,会判断accept队列,若是accept队列满了,就会drop,即把这个syn包丢掉了。到这里,基本上缘由已经查明了。

如何优化

按照以前的分析,大概定位到是由于accept队列满了,咱们经过ss -lnt查看下:
        
1
2
        
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 50 *:20990 *:*
上面看到的第二列Send-Q 表示第三列的listen端口上的accept队列最大为50,第一列Recv-Q为accept队列当前使用了多少。
accept队列的大小取决于:min(backlog, somaxconn) . backlog是在socket建立的时候传入的,somaxconn是一个os级别的系统参数。
syn队列的大小取决于:max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)。不一样版本的os会有些差别。
在这个case中,由于用户的程序发布拉入后,有大量的客户端发起请求,从而致使应用的accept队列满了,而后致使syn被丢弃。用户的应用上配置的backlog为50,因此发现这个现象后,通知研发去更新了dubbo应用的backlog,同时进行发布验证,发现问题已经消失了,至此问题解决。

总结

经过文章对故障的分析,你们了解了syn队列和accept队列的一些知识,同时也了解了如何去观测和优化。其实在生产环境中,这种问题比较常见,也很容易被忽视,但愿这篇分析对你们有所帮助。
最后引用下阿里童鞋的一句话:
每一个具体问题都是最好学习的机会,光看书理解确定是不够深入的,请珍惜每一个具体问题,碰到后可以把前因后果弄清楚。

博客原文: https://leeweir.github.io/2019/10/21/一个-connect-timeout-故障排查/
官方资讯*最新技术*独家解读

本文分享自微信公众号 - Go Official Blog(Go_Official_Blog)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。linux

相关文章
相关标签/搜索