先来回顾下三次握手里面涉及到的问题:
1. 当 client 通过 connect 向 server 发出 SYN 包时,client 会维护一个 socket 等待队列,而 server 会维护一个 SYN 队列
2. 此时进入半链接的状态,如果 socket 等待队列满了,server 则会丢弃,而 client 也会由此返回 connection time out;只要是 client 没有收到 SYN+ACK,3s 之后,client 会再次发送,如果依然没有收到,9s 之后会继续发送
3. 半连接 syn 队列的长度为 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)  决定
4. 当 server 收到 client 的 SYN 包后,会返回 SYN, ACK 的包加以确认,client 的 TCP 协议栈会唤醒 socket 等待队列,发出 connect 调用
5. client 返回 ACK 的包后,server 会进入一个新的叫 accept 的队列,该队列的长度为 min(backlog, somaxconn),默认情况下,somaxconn 的值为 128,表示最多有 129 的 ESTAB 的连接等待 accept(),而 backlog 的值则由 int listen(int sockfd, int backlog) 中的第二个参数指定,listen 里面的 backlog 的含义请看这里。需要注意的是,一些 Linux 的发型版本可能存在对 somaxcon 错误 truncating 方式
6. 当 accept 队列满了之后,即使 client 继续向 server 发送 ACK 的包,也会不被相应,此时,server 通过 /proc/sys/net/ipv4/tcp_abort_on_overflow 来决定如何返回,0 表示直接丢丢弃该 ACK,1 表示发送 RST 通知 client;相应的,client 则会分别返回 read timeout 或者 connection reset by peer。上面说的只是些理论,如果服务器不及时的调用 accept(),当 queue 满了之后,服务器并不会按照理论所述,不再对 SYN 进行应答,返回 ETIMEDOUT。根据这篇文档的描述,实际情况并非如此,服务器会随机的忽略收到的 SYN,建立起来的连接数可以无限的增加,只不过客户端会遇到延时以及超时的情况。

可以看到,整个 TCP stack 有如下的两个 queue:
1. 一个是 half open(syn queue) queue(max(tcp_max_syn_backlog, 64)),用来保存 SYN_SENT 以及 SYN_RECV 的信息。
2. 另外一个是 accept queue(min(somaxconn, backlog)),保存 ESTAB 的状态,但是调用 accept()。

注意,之前我对 Recv-Q/Send-Q 的理解有些误差,使用 ss 获取到的 Recv-Q/Send-Q 在 LISTEN 状态以及非 LISTEN 状态所表达的含义是不同的。从 tcp_diag.c 源码中可以看到二者的区别:

LISTEN 状态: Recv-Q 表示的当前等待服务端调用 accept 完成三次握手的 listen backlog 数值,也就是说,当客户端通过 connect() 去连接正在 listen() 的服务端时,这些连接会一直处于这个 queue 里面直到被服务端 accept();Send-Q 表示的则是最大的 listen backlog 数值,这就就是上面提到的 min(backlog, somaxconn) 的值。
其余状态: 非 LISTEN 状态之前理解的没有问题。Recv-Q 表示 receive queue 中的 bytes 数量;Send-Q 表示 send queue 中的 bytes 数值。

要理解上面总结的这些,可以参见下这两个案例(12)。

通过 "SYNs to LISTEN sockets dropped" 以及 "times the listen queue of a socket overflowed" 这两个 netstat -s 获取到的 TCP 状态,可以很快的发现系统存在的一些问题。
任何一个包含 "dropped" 或者 "overflowed" 并且数值一直居高不下的 metric 从字面含义理解来看,都不是一个好现象。

对于 Nginx 来说,backlog 的默认值为 511,这个可以通过 ss/netstat 的 Send-Q 确认:
State      Recv-Q Send-Q        Local Address:Port          Peer Address:Port
LISTEN     0      511                       *:80                       *:*

可以通过适当的增大 nginx 的 backlog 以及 somaxconn 来增大队列:
listen 80 backlog=1638

上面说了这么多,其实就是为了引入下面这个问题。
我们线上一个基于 Netty 的代码,3.5.12 的版本,监控显示 "times the listen queue of a socket overflowed" 常年居高不下,动辄几十 K,通过 ss,我们发现其 backlog 的值只有 50:
Recv-Q Send-Q           Local Address:Port               Peer Address:Port   
0      50                           *:6928                          *:*        users:(("java",454409,196))

g 了一下,发现这个版本复用了 Java 默认的 50这个值。将其增加到 1024 测试,监控曲线一下子降低到了 0。

除了上面这些,还有一个比较基础的 net.core.netdev_max_backlog,如果内核接受包的速度大于被 userspace 处理的速度,该值定义了可以在接口输入最大的的包数量。

chartbeat 分享了两篇很精彩的文档,其中涉及到了 queue 的一些问题。
Lessons learned tuning TCP and Nginx in EC2 1
Lessons learned tuning TCP and Nginx in EC2 2

ref:
http://madalanarayana.wordpress.com/2014/04/13/learnings-on-tcp-syn/

转自:http://jaseywang.me/2014/07/20/tcp-queue-的一些问题/

Linux-TCP Queue的一些问题的更多相关文章

  1. linux tcp调优

    Linux TCP Performance Tuning News Linux Performance Tuning Recommended Books Recommended Links Linux ...

  2. 深入理解Linux TCP backlog

    本文转载自深入理解Linux TCP backlog 当应用程序调用listen系统调用让一个socket进入LISTEN状态时,需要指定一个参数:backlog.这个参数经常被描述为,新连接队列的长 ...

  3. [转]linux tcp/ip调优

    LINUX tcp/ip性能调优 On 2011年03月15日, in linux, tips, by netoearth 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接 ...

  4. [转帖]Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点

    Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点 http://network.51cto.com/art/201909/603780.htm 可以毫不夸张的说现如今的互联网是基于TC ...

  5. zabbix 监控linux tcp连接数

    zabbix 监控linux tcp连接数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.TCP的状态概述 1>.端口状态转换 2>.TCP 三次握手 3>. ...

  6. Linux TCP漏洞 CVE-2019-11477 CentOS7 修复方法

    CVE-2019-11477漏洞简单介绍 https://cert.360.cn/warning/detail?id=27d0c6b825c75d8486c446556b9c9b68 RedHat用户 ...

  7. [转载] 高流量大并发Linux TCP 性能调优

    原文: http://cenwj.com/2015/2/25/19 本文参考文章为: 优化Linux下的内核TCP参数来提高服务器负载能力 Linux Tuning 本文所面对的情况为: 高并发数 高 ...

  8. linux TCP数据包重传过程----小结

    于TCP/IP协议栈的TCP协议的重传功能是由在linux内核源码(net/ipv4/tcp_output.c)中的函数tcp_retransmit_skb()实现的 代码如下: /* This re ...

  9. Linux TCP队列相关参数的总结 转

        在Linux上做网络应用的性能优化时,一般都会对TCP相关的内核参数进行调节,特别是和缓冲.队列有关的参数.网上搜到的文章会告诉你需要修改哪些参数,但我们经常是知其然而不知其所以然,每次照抄过 ...

  10. Linux TCP/IP parameters reference

    This is a reference of IP networking parameters that are configurable as described in our linux twea ...

随机推荐

  1. x.2

    某些原因,和女朋友分手了,难过 订的M18XR3居然提前了半个多月到货,开心 想想一个人的孤单,还是有点难过 转眼间人生已经过去小半,剩下的除去苟延残喘20年,也就不到20年时间蹦跶.都说人生如戏,既 ...

  2. 移动混合开发之HTML5在移动开发中的准则

    1.尽量单页面开发 2.慎重选择前端UI框架,新手最好自己动手. 3.动画特效达到60fps 4.长度单位是用rem,即字体的宽度,字体宽度可根据 window.width/number.

  3. leetcode Online Judge 150题 解答分析之一 Reverse Words in a String

    问题 Given an input string, reverse the string word by word. For example, Given s = "the sky is b ...

  4. 使用Xmanager远程连接CentOS6.4图形界面详解(图文)

    1.首先安装与下载图形界面GNOMEyum groupinstall "Desktop"yum groupinstall "X Window System"yu ...

  5. (转)整体把握jQuery -jQuery 的原型关系图

    整体把握jQuery -jQuery 的原型关系图 (原)http://www.html5cn.org/article-6529-1.html 2014-7-2 17:12| 发布者: html5cn ...

  6. iOS-打电话、发短信、发邮件、打开浏览器

    - (IBAction)showAlert:(UIButton *)sender { NSString *phoneNumber=@"18500138888"; NSString ...

  7. 如何判断pc或者移动端

    <script type="text/javascript"> var userAgentInfo = navigator.userAgent; var Agents ...

  8. 我的第一个HTML的程序

    <html> <head><title>title为显示标签页的内容</title></head> <body> <h1& ...

  9. MISC-极客大挑战-pen_and_apple.rar

    额   一道MISC的题目 关键词:NTFS数据流隐藏 链接:http://pan.baidu.com/s/1c14PM3A 密码:d7hn 拿到的是一个rar压缩文件,解压得到一个无节操的最近很流行 ...

  10. SqlServer性能优化 提高并发性能二(九)

    补充上一篇修改用非聚集索引: update Employee set age=age+1 from Employee with(index=nc_Employee_Age) where age< ...