多队列 部分队列没有包_记一次TCP全队列溢出问题排查过程

简介:记一次TCP全队列溢出问题排查过程

1. 前言

本文排查的问题是经典的TCP队列溢出问题,因TCP队列问题在操作系统层面没有明显的指标异常,容易被忽略,故把排查过程分享给大家。

2. 问题描述

A服务调用B服务接口超时,B服务主机IOWAIT高,具体超时情况分为两种:

  • A服务的请求在B服务日志中可查到,但B服务的响应时间超过了A服务的等待超时时间3S。
  • A服务的请求在B服务日志中无法查到。

3. 问题分析

此种超时请求集中在很短的一段时间(通常在2分钟之内),过后便恢复正常,所以很难抓到问题现场分析原因,只能搭建测试环境,A服务持续请求B服务,在B服务主机上通过DD命令写入大量数据造成主机IOWAIT高,同时通过TCPDUMP在两端抓包分析。
部分服务超时日志:

  • 服务A:Get http://xxx&id=593930: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
  • 服务B: "GET xxx&id=593930 HTTP/1.1" 200 64 "-" "Go-http-client/1.1" "-" "-" 165000(单位微秒)

服务A发起请求3S后没有收到服务B响应,断开连接,服务B日志显示处理时长为0.165S,远低于3S,服务A侧看服务B的响应时间为网络传输时间、TCP队列排队时间及服务B应用程序处理时间之和,因为是内网测试,网络传输时间可以忽略,主要排查方向应为TCP队列排队时间。

4. 抓包数据分析

情景1:服务A及服务B均有连接日志打印。
服务A端数据包分析:
09:51:43.966553000 服务A发起 GET请求的数据包如下:

048f96698a7bf0cdd6458023a9dbc934.png
图1:服务A发起GET请求


09:51:46.966653000 服务A发起 GET请求3s(即服务A设置的等待超时时长)后,因未收到服务B响应,服务A向服务B发起FIN主动断开连接。

86ac783d8bc23a756f7a787888acd2ca.png
图2:服务A等待超时主动断开连接


09:51:59.958195000 服务A发起http请求16s后收到服务B的http响应报文,因服务A已主动关闭该连接,故直接回复RST。

8adbde399fbc38e1c0b797ecfdddd085.png
图3: 服务B16s后响应

服务B端数据包分析:
09:51:44.062095000 服务B收到服务A发送的http请求包。

c2be8c7e608a8cc21c653dd445458740.png
图4:服务B收到服务A的请求


9:51:59.936169000 服务B响应服务A,服务B从接收到http请求报文至响应http请求总用时约为15s多,但服务B打印的日志响应时长约为0.165s。

144e0bf2c87cb435ba78cb3b96c0f2f2.png
图5:服务B15S后响应

1bd5191c2eb7a4f6f424f1ce2aa7357a.png
图6:服务B日志显示响应时间0.165s

情景2:服务A有连接日志,服务B无连接日志。
服务A端数据包分析:
09:51:43.973791000 服务A向服务B发送一个http请求数据包,随后收到服务B重传的第二次握手的syn+ack包,超过3s未收到服务B的http响应后断开连接。

402fb04a9f40c95cd0b3124a93bad456.png
图7:服务B重传syn+ack

服务B端数据包分析:
服务B重传了第二次握手的syn+ack包,收到服务A的http请求,服务B忽略,未响应,服务A等待超时后断开了连接。

7ed08c688c0f5f9e4003f65479b33b32.png
图8: 服务B忽略服务A请求

5. 根因分析

TCP在三次握手过程中内核会维护两个队列:

  • 半连接队列,即SYN队列
  • 全连接队列,即ACCEPT队列

d346f16922007185d4de87fa2c21aafd.png
图9:TCP队列

TCP三次握手过程中,第一次握手server收到client的syn后,内核会把该连接存储到半连接队列中,同时回复syn+ack给client(第二次握手),第三次握手时server收到client的ack,如果此时全连接队列未满,内核会把连接从半连接队列移除,并将其添加到 accept 队列,等待应用进程调用 accept 函数取出连接,如果全连接队列已满,内核的行为取决于内核参数tcp_abort_on_overflow:

  • tcp_abort_on_overflow=0,server会丢弃client的ack。
  • tcp_abort_on_overflow=1,server 会发送 reset 包给 client。

默认值是0。
情景1的抓包数据显示连接已经进入全连接队列,但是服务B日志显示的连接时间晚了15S多,说明连接在队列里等待了15S后才被应用处理。
情景2的抓包数据显示全连接队列已溢出,内核根据tcp_abort_on_overflow的值为0丢弃了服务A的ack,超过了服务A的超时等待时间。
结论:服务B主机在IO达到瓶颈的情况下,系统CPU时间主要消耗在等待IO响应及处理软中断上,服务B应用程序获取的CPU时间有限,无法及时调用 accept 函数把连接取出并处理,导致TCP全队列溢出或队列等待时间过长,超过了服务A的超时时间。

6. 如何观察和调整tcp全队列

68e205cb83967318c21c9ad342af66df.png
图10: TCP全队列观察方法

当连接处于listen状态时:

  • Recv-Q:目前全连接队列的大小
  • Send-Q:目前全连接最大队列长度

当Recv-Q > Send-Q时表示全队列溢出,可通过执行netstat -s | grep "overflowed"命令观察溢出情况,查看累计溢出次数,如果需观察一段时间内的全队列溢出情况,建议使用监控系统采集数据,比如prometheus。

8e744231a87b8bc24f1702ef5a10fa85.png
图11: TCP队列溢出监控


TCP 全连接队列最大值取决于min(somaxconn, backlog),其中:

  • somaxconn可通过内核参数/proc/sys/net/core/somaxconn设置,默认值是128。
  • backlog是 listen(int sockfd, int backlog) 函数中的 backlog 大小,Nginx 默认值是 511,可以通过修改配置文件设置其长度。

7. 结语

本次问题,因为服务对成功率要求很高,所以先通过调大服务B主机/proc/sys/net/core/somaxconn参数值及服务A的超时时间来缓解超时问题,暂时保证了接口成功率。但要从根本上解决问题,仍需解决诱因io瓶颈,因为服务B主机挂载的共享sas存储集群上有其他客户的主机偶尔io很大,影响了整个集群的性能。为解决此问题,更换为独享的ssd盘,并通过blktrace+fio分析,将io调度算法修改为noop,io性能明显提升,TCP队列溢出问题也随之解决。

作者:陈立华

原文链接

本文为阿里云原创内容,未经允许不得转载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[蓝桥杯2015决赛]完美正方形-dfs

题目描述 如果一些边长互不相同的正方形,可以恰好拼出一个更大的正方形,则称其为完美正方形。 历史上,人们花了很久才找到了若干完美正方形。 比如:如下边长的22个正方形 2 3 4 6 7 8 12 13 14 15 16 17 18 21 22 23 24 26 27 28 …

销量预测设计

目录一、算法计算逻辑举个直观的例子销量预测二、项目背景三、算法与业务的关系四、关于业务人员对未来外部变量“打标签”:五、关于预测颗粒度:六、关于预测准确率和影响准确率的因素:一、算法计算逻辑 销量预测算法建模要用到的数据&#…

.NET Core开发实战(第23课:静态文件中间件:前后端分离开发合并部署骚操作)--学习笔记(下)...

23 | 静态文件中间件:前后端分离开发合并部署骚操作这里还有一个比较特殊的用法一般情况下,我们前后端分离的架构,前端会编译成一个 index.html 文件和若干个 CSS 文件和 JavaScript 和图片文件CSS 文件和 JavaScript 和图片文件一般会部署在…

springboot 历史版本文档_乘风破浪,SpringBoot入门

SpringBoot入门篇前言在普通的java项目中,大量的xml文件配置起来相当繁琐,导致了开发效率非常低下,整合第三方框架的配置可能会存在冲突问题导致部署效率低,打包方式是将项目打成一个war包放入到tomactwebapps目录下执行。简单来说…

简洁直观解释精确率、召回率、F1 值、ROC、AUC

混淆矩阵 当我们在做二分类预测时,把预测情况与实际情况的所有结果两两混合,结果就会出现以下4种情况,就组成了混淆矩阵。 P(Positive):代表正样本N(Negative):代表负样…

基于Tensorflow搭建卷积神经网络CNN(水果识别)保姆及级教程

项目介绍 TensorFlow2.X 搭建卷积神经网络(CNN),实现水果识别。搭建的卷积神经网络是类似VGG的结构(卷积层与池化层反复堆叠,然后经过全连接层,最后用softmax映射为每个类别的概率,概率最大的即为识别结果…

如何编写高性能的C#代码(四)字符串的另类骚操作

原文来自互联网,由长沙DotNET技术社区编译。如译文侵犯您的署名权或版权,请联系小编,小编将在24小时内删除。作者介绍:史蒂夫戈登(Steve Gordon)是Microsoft MVP,Pluralsight的作者,…

statusbar 尺寸 显示图标_移动端页面设计规范尺寸大起底 - 椰树飘香

移动端尺寸繁多,包括IOS和安卓,尺寸多达十余种,所以移动页面尺寸的适配一直是前端和设计的头疼。今天来总结一下当前市场上的一些移动端尺寸,方便设计师和前端去考虑适配。但是最好还是针对自己的产品做调查,根据数据去…

新建项目上传gitee(码云)教程

登录码云 新建一个仓库后,复制HTTPS地址: 本地项目操作 打开需要上传gitee的项目文件夹,并打开Git Bash窗口 本地仓库初始化: git init添加到暂存区 git add .提交到本地仓库 git commit -m "first commit"关联到…

OpenSilver: 通过WebAssembly 复活Silverlight

本月早些时候,Userware发布了第一个版本的OpenSilver,微软Silverlight 的开源重新实现。OpenSilver 通过WebAssembly 实现无需任何其他插件在 浏览器上运行。OpenSilver 的当前版本可作为"技术预览"版本提供,它涵盖了大约 60% 的原…

db2有主键时默认hash分区_MySQL分区表最佳实践

前言:分区是一种表的设计模式,通俗地讲表分区是将一大表,根据条件分割成若干个小表。但是对于应用程序来讲,分区的表和没有分区的表是一样的。换句话来讲,分区对于应用是透明的,只是数据库对于数据的重新整…

程序员过关斩将-- 喷一喷坑爹的面向UI编程

点击上方“蓝字”关注我们菜菜哥,求你个事呗?说来听听,假装你男朋友可不干不是哦,是正经事。前几天一个项目UI改了,好多人跟着加班修改,怎么样尽量避免这种情况呢?UI修改顶多和客户端开发人员关…

python二维散点分布图_深入理解皮尔逊相关系数amp;python代码

1.常见理解误区(1)计算出变量A和变量B的皮尔逊相关系数为0,不代表A和B之间没有相关性,只能说明A和B之间不存在线性相关关系。例:温度和冰淇淋销量之间的散点图像如下,可以发现大致成二次函数图像&#xff0…

hdu4911 Inversion-归并排序

解题思路: 如果原序列的逆序对数大于交换次数,那么最少的逆序对数量就是原序列逆序对-交换次数。 如果原序列的逆序对数小于等于交换次数,那么最少的逆序对数量为0,因为交换次数超过逆序对数,可以把这些逆序对全部消除…

【.net core】电商平台升级之微服务架构应用实战

一、前言这篇文章本来是继续分享IdentityServer4 的相关文章,由于之前有博友问我关于微服务相关的问题,我就先跳过IdentityServer4的分享,进行微服务相关的技术学习和分享。微服务在我的分享目录里面是放到四月份开始系列文章分享的&#xff…

c语言将一个已知头结点的单链表逆序_C语言实现常用数据结构:静态链表数组实现(第5篇)...

「今天是学习C语言第 148 天」纸上学来终觉浅,绝知此事要躬行。—— 陆游「冬夜读书示子聿」# 静态链表使用数组实现,利用数组下标代替指针,从而实现数据结点之间的先后关系。实现要点:1.数组下标为0的位置为头结点,指…

集成平台集群任务动态分派

源宝导读:MIP集成平台是为了解决企业大量异构系统之间快速、稳定集成的需要,助力企业数字化转型,明源云自主研发的平台系统。本文将对"事件任务分派"场景的架构设计以及实践成果进行分享。背景MIP集成平台是为了解决企业大量异构系…

dotcpp1115 DNA-打印图案

题目描述 小强从小就喜欢生命科学,他总是好奇花草鸟兽从哪里来的。终于, 小强上中学了,接触到了神圣的名词–DNA.它有一个双螺旋的结构。这让一根筋的小强抓破头皮,“要是能画出来就好了” 小强喊道。现在就请你帮助他吧 输入 输…

akb48_AKB48里历史——六年的终结

注:这是2012年发行的一本在BUBUKA连载的基础上补充了一些内容的粉丝公式教科书,从里面找了部分内容翻译了一下,节选的内容主要说的是2011年的事情,以当时作者的视角,是AKB48第一次新老粉丝换代的时期。前田敦子和大岛优…

[头脑风暴] 解读Docker Bridge网络模型

背景这几天在研究Kubernetes, 遇到一个有意思的nodejs镜像:luksa/kubia# 不带端口映射启动容器 docker run -it -d luksa/kubia # 连接到默认的Bridge网桥,容器IP是 172.17.0.2之后,在宿主机使用容器IP和8080 端口可访问该容器…