故障发散-Recv-Q阻塞
2021/5/17 18:28:35
本文主要是介绍故障发散-Recv-Q阻塞,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
之前有个开发遇到个生产问题,开发发现有时候CS之间的心跳直接丢了,查看日志发现客户端一直没收到心跳报文,但服务端其实已经把报文发了,觉得很奇怪,TCP 是可靠链接,不可能丢了吧,最终是发现了netstat 里的recv-q 有积压导致的,问题虽然解决了,但还是需要复盘一下,看看细节。
先看下啥是Recv-Q 和 Send-Q
Recv-Q
Established: The count of bytes not copied by the user program connected to this socket. Listening: Since Kernel 2.6.18 this column contains the current syn backlog.
单位是字节,是表示程序总共还有多少字节的数据没有从内核空间的套接字缓存拷贝到用户空间。
Send-Q
Established: The count of bytes not acknowledged by the remote host. Listening: Since Kernel 2.6.18 this column contains the maximum size of the syn backlog.
单位是字节,是表示远程主机还没有ack的数据包的大小。
这2个Q本质上操作的数据其实是socket 上的缓存数据以及用户进程的缓存数据,对应的分别是recv() 和 send() 方法, 之后的发送接收都是纯TCP来操作的,和socket关系了,所以一般发现recv-q 阻塞了,其实和tcp关系已经不大了,因为tcp的可靠性让服务器的socket 收到了来对对端的数据,但因为某些原因,应用程序没有从socket的缓存 上读数据,导致了socket的buffer 慢慢积压,堆满,这时候,tcp会告知发送方,接收端窗口大小关闭了(win=0),这个操作保证了socket 缓存不会溢出,如果发送端不管窗口大小,强行发送超过窗口大小的数据,则tcp会直接丢弃该报文。
一般可以socket 缓存区满了可以检查代码,是不是存在链接泄露等问题,如果不是,则可以考虑修改内核提高linux的性能。
基于这种场景的TCP 的性能优化
socket 缓冲区阻塞,优化思路无非就是加大缓冲区的大小,加快tcp的回收,
#网络kernel socket 预留的发送缓冲的内存数量,分为读写,单位是字节。 net.core.rmem_default = 16777216 net.core.rmem_max = 16777216 net.core.wmem_default = 16777216 net.core.wmem_max = 16777216 # tcp socket 预留的缓存,分为三个字段,min, default, max,单位是字节 net.ipv4.tcp_rmem = 4096 873800 16777216 net.ipv4.tcp_wmem = 4096 873800 16777216 # 调整TCP的内存大小,其单位是页,1页等于4096字节,分为三个字段,low, pressure, high # low:当TCP使用了低于该值的内存页面数时,TCP不会考虑释放内存。 # pressure:当TCP使用了超过该值的内存页面数量时,TCP试图稳定其内存使用,进入pressure模式,当内存消耗低于low值时则退出pressure状态。 # high:允许所有tcp sockets用于排队缓冲数据报的页面量,当内存占用超过此值,系统拒绝分配socket,后台日志输出"TCP: too many of orphaned sockets"。 # 根据下面high tcp_mem的值进行计算,当tcp 占用内存超过 16777216*4096/1024/1024=65536MB 的时候,就会开始报错 net.ipv4.tcp_mem = 6177504 8236672 16777216 # somaxconn是指服务端所能accept即处理数据的最大客户端数量,即完成连接上限, net.core.somaxconn = 1024 #tcp_max_syn_backlog是指定所能接受SYN同步包的最大客户端数量,即半连接上限, 有些文章建议也调大这个参数,个人理解是因为在三次握手完成之前socket就存在了,所以在send()和recv() 之前,connect()到appect()之间,如果有大量的半开链接,也会导致类似的问题,但应该不会造成recv-q的阻塞。 tcp_max_syn_backlog = 2048
- 补一个socket 和 tcp 之间的关系
SOCKET:
TCP-SOCKET:
个人公众号, 分享一些日常开发,运维工作中的日常以及一些学习感悟,欢迎大家互相学习,交流
这篇关于故障发散-Recv-Q阻塞的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享