您的位置:时时app平台注册网站 > 时时app平台注册网站 > 关于TCP 半连接队列和全连接队列

关于TCP 半连接队列和全连接队列

2019-11-21 02:54

汤姆cat和Nginx中的Accept队列参数

汤姆cat私下认可短连接,backlog(汤姆cat里面包车型地铁术语是Accept count卡塔 尔(英语:State of Qatar)Ali-tomcat暗中认可是200, Apache 汤姆cat默许100。
Nginx默认是511

参考:

server5

那就是说全连接队列满了会影响半连接队列吗?

来看贰回握手第一步的源代码(http://elixir.free-electrons.com/linux/v2.6.33/source/net/ipv4/tcp_ipv4.c#L1249):

图片 1

image.png

TCP三回握手第一步的时候如若全连接队列满了会潜移默化率先步drop 半连接的产生。大约流程的如下:

tcp_v4_do_rcv->tcp_rcv_state_process->tcp_v4_conn_request
//如果accept backlog队列已满,且未超时的request socket的数量大于1,则丢弃当前请求  
  if(sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_yong(sk)>1)
      goto drop;

查看 全连接队列

上边见到的 13 times ,表示全连接队列溢出的次数,隔几分钟推行下,如若这么些数字一贯在大增的话料定全连接队列不经常满了。

netstat -s |egrep "listen|LISTEN"
13 times the listen queue of a socket overflowed
54 SYNs to LISTEN sockets dropped

ss -lnt
State       Recv-Q  Send-Q        Local Address:Port                 Peer Address:Port
LISTEN       0        50               *:7999                              *:*  

地点见到的第二列Send-Q 值是50,表示第三列的listen端口上的全连接队列最大为50,第一列Recv-Q为全连接队列当前应用了多少。
全连接队列的深浅决计于:min(backlog, somaxconn) . backlog是在socket成立的时候传出的,somaxconn是三个os级其余系统参数。

cat /proc/sys/net/core/somaxconn
16384

11        10        *:3306              *:*

总结

全连接队列、半连接队列溢出这种难题非常轻巧被忽视,可是又超级重要,极度是对于有个别短连接使用(比方Nginx、PHP,当然他们也是永葆长连接的卡塔 尔(英语:State of Qatar)更易于产生。 风姿浪漫旦溢出,从cpu、线程状态看起来都比较健康,然而压力上不去,在client看来rt也正如高(rt=互连网 排队 真正服务时间卡塔尔国,不过从server日志记录的实在服务时间来看rt又非常的短。

别的就是jdk、netty等部分框架暗许backlog超级小,可能有个别情形下引致品质上不去,例如@毕玄 境遇的这些 《netty新建连接并发数非常小的case》
都以相像原因

希望由此本文能够帮大家知道TCP连接进度中的半连接队列和全连接队列的概念、原理和效果与利益,更要紧的是有如何目的能够显明看见那几个主题材料。

其余各个具体难点都以最佳学习的机缘,光看书理解鲜明是远远不足深入的,请珍视各类具体难题,碰着后能够把来踪去迹弄清楚。

自家的别样几篇跟互连网难点相关的篇章,也很风趣,借着案例来精晓好概念和法规,希望对大家也不怎么帮忙

https://www.atatech.org/articles/60633

https://www.atatech.org/articles/73174

https://www.atatech.org/articles/73289

https://www.atatech.org/articles/76138

末尾谢谢 @梦实 在此个进程中提供的提携


仿效随笔:

http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html

http://www.cnblogs.com/zengkefu/p/5606696.html

http://www.cnxct.com/something-about-phpfpm-s-backlog/

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

http://jin-yang.github.io/blog/network-synack-queue.html#

http://blog.chinaunix.net/uid-20662820-id-4154399.html

https://www.atatech.org/articles/12919

图片 2
这里有几个体系:syns queue(半老是队列卡塔 尔(阿拉伯语:قطر‎;accept queue(全连接队列卡塔尔国。
三次握手进程中:
首先步: server 收到 client 的 syn 后,把那些再而三音信放到半老是队列中,
第二步: 同不经常间恢复生机 syn ack 给 client
其三步: server 收到 client 的 ack,如果那时全连接队列没满,那么从半三回九转队列拿出这几个三回九转的消息放入到全连接队列中,不然按tcp_abort_on_overflow提示的实践。
那个时候纵然全连接队列满了而且 tcp_abort_on_overflow 是0的话,server过风度翩翩段时间再度发送syn ack给client(也便是重新走握手的第二步卡塔 尔(阿拉伯语:قطر‎,借使client超时等待超级短,client就十分轻易相当了。

image.png

netstat -s

[root@server ~]#  netstat -s | egrep "listen|LISTEN" 
667399 times the listen queue of a socket overflowed
667399 SYNs to LISTEN sockets ignored

比方说上边看见的 667399 times ,表示全连接队列溢出的次数,隔几分钟实践下,纵然那些数字一贯在加多的话料定全连接队列偶然满了。

查看半连连队列

大小决定于:max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog),区别版本的os会稍稍出入。

cat /proc/sys/net/ipv4/tcp_max_syn_backlog
16384

Nginx默认是511

浓郁精通TCP握手进程中国建工业总会公司连接的流水生产线和队列

图片 3

(图片来源于:http://www.cnxct.com/something-about-phpfpm-s-backlog/)

如上图所示,这里有七个系列:syns queue(半三番五次队列卡塔 尔(英语:State of Qatar);accept queue(全连接队列卡塔 尔(英语:State of Qatar)

二遍握手中,在首先步server收到client的syn后,把有关音讯放到半连连队列中,同有的时候间复苏syn ack给client(第二步卡塔尔;

比如syn floods 攻击就是针对半连接队列的,攻击方不停地建连接,但是建连接的时候只做第一步,第二步中攻击方收到server的syn ack后故意扔掉什么也不做,导致server上这个队列满其它正常请求无法进来

其三步的时候server收到client的ack,假如此刻全连接队列没满,那么从半连接队列拿出有关消息放入到全连接队列中,不然按tcp_abort_on_overflow提示的施行。

此时借使全连接队列满了还要tcp_abort_on_overflow是0的话,server过风流倜傥段时间再次发送syn ack给client(也正是重新走握手的第二步卡塔尔,假设client超时等待非常短,就比较轻易格外了。

在大家的os中retry 第二步的默许次数是2(centos暗中认可是5次卡塔 尔(英语:State of Qatar):

net.ipv4.tcp_synack_retries = 2
cat /proc/sys/net/ipv4/tcp_abort_on_overflow 
0

主题素材汇报

例行TCP建连接一次握手进程:

图片 4

image.png

  • 首先步:client 发送 syn 到server 发起握手;
  • 第二步:server 收到 syn后回复syn ack给client;
  • 其三步:client 收到syn ack后,回复server三个ack表示收到了server的syn ack(当时client的56911端口的接连几天已然是established卡塔尔国

从难题的陈诉来看,有一点像TCP建连接的时候全连接队列(accept队列卡塔尔满了,特别是症状2、4. 为了验证是以此原因,立刻通过 ss -s 去看队列的溢出总计数据:

667399 times the listen queue of a socket overflowed

一再看了两遍之后开掘这些overflowed 一向在追加,那么可以简单的说的是server上全连接队列一定溢出了

接着查看溢出后,OS怎么管理:

# cat /proc/sys/net/ipv4/tcp_abort_on_overflow
0

tcp_abort_on_overflow 为0表示大器晚成旦一回握手第三步的时候全连接队列满了那么server扔掉client 发过来的ack(在server端以为连接还未创设起来卡塔尔

为了表达客商端应用代码的非常跟全连接队列满有关系,作者先把tcp_abort_on_overflow改良成 1,1象征第三步的时候假如全连接队列满了,server发送叁个reset包给client,表示废掉那个抓手进度和这几个三回九转(本来在server端这几个三回九转就还没有建构起来卡塔尔。

继之测验然后在客商端特别中得以看出数不胜数connection reset by peer的不当,到此证实客商端错误是其生机勃勃缘故促成的。

于是乎开垦同学翻看java 源代码发掘socket 暗中认可的backlog(这一个值调控全连接队列的大大小小,后边再详述卡塔 尔(阿拉伯语:قطر‎是50,于是改大重新跑,经过十三个时辰以上的压测,这么些似是而非叁回都没现身过,同期overflowed 也不再增添了。

到此问题一下子就解决了,简单的话TCP二次握手后有个accept队列,进到这么些队列工夫从Listen形成accept,默许backlog 值是50,十分轻松就满了。满了随后握手第三步的时候server就忽视了client发过来的ack包(隔风流倜傥段时间server重发握手第二步的syn ack包给client卡塔 尔(阿拉伯语:قطر‎,假如那个一连平素排不上队就格外了。

server2

设若TCP连接队列溢出,有啥目标能够看吗?

上述消除进程有一点点绕,那么下一次再次出现身犹如主题素材有哪些越来越快更明显的手段来认同那些难点吗?

3.selector向来不死灭重新营造,一贯用的都以多少个。

实行表明下方面包车型客车知道

把java中backlog改成10(越小越轻松溢出卡塔尔,继续跑压力,那个时候client又起始报那叁个了,然后在server上经过 ss 命令观望到:

Fri May  5 13:50:23 CST 2017
Recv-Q Send-QLocal Address:Port  Peer Address:Port
11         10         *:3306               *:*

依照前边的掌握,此时大家能来看3306以此端口上的劳动全连接队列最大是10,可是今后有拾叁个在队列仲春等待进队列的,料定有贰个总是进不去队列要overflow掉

overflowed和ignored居然总是相通多,何况都以同台扩张,overflowed表示全连接队列溢出次数,socket ignored表示半连接队列溢出次数,没这么巧啊。

题目叙述

JAVA的client和server,使用socket通信。server使用NIO。
1.间歇性的出现client向server建立连接三次握手已经完成,但server的selector没有响应到这连接。
2.出问题的时间点,会同时有很多连接出现这个问题。
3.selector没有销毁重建,一直用的都是一个。
4.程序刚启动的时候必会出现一些,之后会间歇性出现。

浓烈通晓TCP握手进程中国建工业总会公司连接的流程和队列

ss 命令

[root@server ~]# ss -lnt
Recv-Q Send-Q Local Address:Port  Peer Address:Port 
0        50               *:3306             *:* 

上边见到的第二列Send-Q 表示第三列的listen端口上的全连接队列最大为50,第一列Recv-Q为全连接队列当前使用了略微

全连接队列的尺寸决定于:min(backlog, somaxconn) . backlog是在socket创设的时候传出的,somaxconn是三个os级其他种类参数

半老是队列的轻重缓急决意于:max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)。 差别版本的os会微微差距

Recv-Q Send-Q Local Address:Port  Peer Address:Port

容器中的Accept队列参数

汤姆cat暗中同意短连接,backlog(汤姆cat里面包车型地铁术语是Accept count卡塔 尔(阿拉伯语:قطر‎Ali-tomcat默许是200, Apache Tomcat默许100.

#ss -lnt
Recv-Q Send-Q   Local Address:Port Peer Address:Port
0       100                 *:8080            *:*

Nginx默认是511

$sudo ss -lnt
State  Recv-Q Send-Q Local Address:PortPeer Address:Port
LISTEN    0     511              *:8085           *:*
LISTEN    0     511              *:8085           *:*

因为Nginx是多进度形式,也正是多少个经过都监听同叁个端口以尽量防止上下文切换来提高质量

//如若accept backlog队列已满,且未超时的request socket的数额超越1,则扬弃当前倡议

有关TCP 半一而再延续队列和全连接队列

目前遭遇多个client端连接极度难点,然后定位解析并查看各类材质小说,对TCP连接队列有个深深的通晓

查资料进程中发觉未有成文把那多少个体系以至怎么观望他们的指标说驾驭,希望因此那篇文章能把他们说清楚一些

16422 SYNs to LISTEN sockets dropped

进程中发觉的三个古怪难题

[root@server ~]# date; netstat -s | egrep "listen|LISTEN" 
Fri May  5 15:39:58 CST 2017
1641685 times the listen queue of a socket overflowed
1641685 SYNs to LISTEN sockets ignored

[root@server ~]# date; netstat -s | egrep "listen|LISTEN" 
Fri May  5 15:39:59 CST 2017
1641906 times the listen queue of a socket overflowed
1641906 SYNs to LISTEN sockets ignored

如上所示:
overflowed和ignored居然总是同样多,并且都以联合增添,overflowed代表全连接队列溢出次数,socket ignored表示半连接队列溢出次数,没那样巧啊。

翻看内核源代码(http://elixir.free-electrons.com/linux/v3.18/source/net/ipv4/tcp_ipv4.c):

图片 5

image.png

能够看出overflow的时候鲜明会drop (socket ignored卡塔尔,也便是drop一定大于等于overflow。

还要自己也查看了其余几台server的那多少个值来评释drop一定大于等于overflow:

server1
150 SYNs to LISTEN sockets dropped

server2
193 SYNs to LISTEN sockets dropped

server3
16329 times the listen queue of a socket overflowed
16422 SYNs to LISTEN sockets dropped

server4
20 times the listen queue of a socket overflowed
51 SYNs to LISTEN sockets dropped

server5
984932 times the listen queue of a socket overflowed
988003 SYNs to LISTEN sockets dropped

全连接队列、半连接队列溢出这种主题材料超级轻松被忽略,不过又很首要,极其是对此一些短连接使用(比方Nginx、PHP,当然他们也是援助长连接的卡塔 尔(阿拉伯语:قطر‎更便于产生。 大器晚成旦溢出,从cpu、线程状态看起来都比较正规,不过压力上不去,在client看来rt也正如高(rt=网络 排队 真正服务时间卡塔 尔(英语:State of Qatar),可是从server日志记录的真的服务时间来看rt又超短。

深入分析难题

从地点的实在抓包来看不是reset,而是server忽视那些包,然后client重传,一定次数后client以为不行,然后断开连接。

越发考虑

意气风发经client走完第三步在client看来连接已经成立好了,可是server上的附和连接实际未有希图好,那时候固然client发多少给server,server会怎么管理吧?(有同学说会reset,依旧推行看看卡塔尔

先来看一个事例:

图片 6

image.png

(图片来自:http://blog.chinaunix.net/uid-20662820-id-4154399.html)

如上图,150166号包是一次握手中的第三步client发送ack给server,然后150167号包中client发送了三个长度为816的包给server,因为在此个时候client以为连接创设成功,可是server上那些一连实际并未有ready,所以server没有苏醒,生机勃勃段时间后client感到丢包了接下来重传那814个字节的包,一向到过期,client主动发fin包断开该连接。

以此主题材料也叫client fooling,能够看这里:https://github.com/torvalds/linux/commit/5ea8ea2cb7f1d0db15762c9b0bb9e7330425a071 (感谢 @刘欢(浅奕(16:00后答疑) 的提示)

**从下边的骨子里抓包来看不是reset,而是server忽视那个包,然后client重传,一定次数后client感到特别,然后断开连接。
**

image.png

第二步:server 收到 syn后回复syn ack给client;

更加的考虑

State  Recv-Q Send-Q Local Address:PortPeer Address:Port

netstat -s

来看三遍握手第一步的源代码(http://elixir.free-electrons.com/linux/v2.6.33/source/net/ipv4/tcp_ipv4.c#L1249):

为了印证顾客端应用代码的不行跟全连接队列满有关系,作者先把tcp_abort_on_overflow改过成 1,1意味第三步的时候要是全连接队列满了,server发送叁个reset包给client,表示废掉那个抓手进度和这些三番五次(本来在server端那些三番五次就尚未营造起来卡塔尔。

如上所示:

容器中的Accept队列参数

667399 SYNs to LISTEN sockets ignored

server3

Fri May  5 13:50:23 CST 2017

倘使TCP连接队列溢出,有啥指标能够看吗?

如上海教室所示,这里有七个系列:syns queue(半一而再队列卡塔尔国;accept queue(全连接队列卡塔 尔(阿拉伯语:قطر‎

这正是说全连接队列满了会影响半接连队列吗?

举例上边看见的 667399 times ,表示全连接队列溢出的次数,隔几分钟实践下,若是那几个数字一向在增添的话肯定全连接队列临时满了。

667399 times the listen queue of a socket overflowed

全连接队列的朗朗上口决意于:min(backlog, somaxconn) . backlog是在socket创设的时候传出的,somaxconn是叁个os级其余系统参数

goto drop;

0        50              *:3306            *:*

再三看了两次之后察觉那些overflowed 一贯在追加,那么能够一览无余的是server上全连接队列一定溢出了

tcp_abort_on_overflow 为0代表假使二遍握手第三步的时候全连接队列满了那么server扔掉client 发过来的ack(在server端感觉连接还未创设起来卡塔 尔(英语:State of Qatar)

第一步:client 发送 syn 到server 发起握手;

0

于是乎开垦同学翻看java 源代码发掘socket 暗中认可的backlog(这些值调节全连接队列的大小,前边再详述卡塔尔国是50,于是改大重新跑,经过十二个钟头以上的压测,那几个指鹿为马一次都没现身过,同时overflowed 也不再扩张了。

988003 SYNs to LISTEN sockets dropped

150 SYNs to LISTEN sockets dropped

翻看内核源代码(http://elixir.free-electrons.com/linux/v3.18/source/net/ipv4/tcp_ipv4.c):

那时如果全连接队列满了还要tcp_abort_on_overflow是0的话,server过风流倜傥段时间再度发送syn ack给client(相当于双重走握手的第二步卡塔 尔(英语:State of Qatar),如若client超时等待超级短,就十分轻易非常了。

Recv-Q Send-QLocal Address:Port  Peer Address:Port

image.png

#ss -lnt

LISTEN    0    511              *:8085          *:*

tcp_v4_do_rcv->tcp_rcv_state_process->tcp_v4_conn_request

1641685 times the listen queue of a socket overflowed

1641906 times the listen queue of a socket overflowed

从难题的陈诉来看,有一点像TCP建连接的时候全连接队列(accept队列卡塔 尔(英语:State of Qatar)满了,非常是症状2、4. 为了验证是以此原因,立时通过 ss -s 去看队列的溢出总计数据:

20 times the listen queue of a socket overflowed

並且本人也查看了其余几台server的那五个值来验证drop一定大于等于overflow:

1641685 SYNs to LISTEN sockets ignored

ss 命令

1.间歇性的出现client向server建构连接三遍握手已经完毕,但server的selector未有响应到那连接。

0      100                *:8080            *:*

如上海体育地方,150166号包是三遍握手中的第三步client发送ack给server,然后150167号包中client发送了一个长度为816的包给server,因为在这里个时候client感到连接建构成功,但是server上这几个一而再实际并未有ready,所以server未有复苏,大器晚成段时间后client感觉丢包了接下来重传那816个字节的包,一贯到过期,client主动发fin包断开该连接。

半一连队列的尺寸决定于:max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)。 分裂版本的os会有一点点差异

图片 7

Tomcat暗中认可短连接,backlog(汤姆cat里面的术语是Accept count卡塔尔国Ali-tomcat私下认可是200, Apache 汤姆cat默许100.

[root@server ~]#  netstat -s | egrep "listen|LISTEN"

图片 8

Fri May  5 15:39:58 CST 2017

能够见到overflow的时候自然会drop (socket ignored卡塔尔国,也等于drop一定大于等于overflow。

Fri May  5 15:39:59 CST 2017

图片 9

那几个标题也叫client fooling,可以看这里:https://github.com/torvalds/linux/commit/5ea8ea2cb7f1d0db15762c9b0bb9e7330425a071(谢谢浅奕的唤醒)

667399 times the listen queue of a socket overflowed

设若client走完第三步在client看来连接已经济建设立好了,但是server上的呼应连接实际并未兵马未动粮草先行有备无患好,那时假如client发多少给server,server会怎么处理啊?(有同学说会reset,依旧举行看看卡塔尔国

[root@server ~]# date; netstat -s | egrep "listen|LISTEN"

图片 10

进而测量检验然后在顾客端特别中能够看到众多connection reset by peer的失实,到此表达客户端错误是其意气风发原因促成的。

其三步的时候server收到client的ack,倘若此刻全连接队列没满,那么从半接连队列拿出有关新闻放入到全连接队列中,否则按tcp_abort_on_overflow提醒的推行。

1641906 SYNs to LISTEN sockets ignored

(图片来自:http://blog.chinaunix.net/uid-20662820-id-4154399.html)

# cat /proc/sys/net/ipv4/tcp_abort_on_overflow

Recv-Q Send-Q  Local Address:Port Peer Address:Port

JAVA的client和server,使用socket通信。server使用NIO。

TCP三遍握手第一步的时候假如全连接队列满了会潜濡默化率先步drop 半连接的发生。差不离流程的如下:

image.png

根据后面包车型客车敞亮,那个时候大家能来看3306那些端口上的服务全连接队列最大是10,但是现在有十二个在队列中和等候进队列的,肯定有三个三翻八遍进不去队列要overflow掉

先来看一个例子:

上述解决进度有一些绕,那么后一次再出新就好像主题素材有怎样越来越快更显眼的招式来承认这几个标题吧?

其三步:client 收到syn ack后,回复server叁个ack表示选取了server的syn ack(那时候client的56911端口的延续已是established卡塔 尔(阿拉伯语:قطر‎

进度中发掘的二个意想不到难点

2.出标题标时间点,会同时有相当多接连出现那几个难题。

net.ipv4.tcp_synack_retries = 2

把java中backlog改成10(越小越轻便溢出卡塔 尔(英语:State of Qatar),继续跑压力,当时client又伊始报这一个了,然后在server上经过 ss 命令观望到:

984932 times the listen queue of a socket overflowed

[root@server ~]# ss -lnt

到此难题解决,一言以蔽之TCP二遍握手后有个accept队列,进到这一个行列手艺从Listen形成accept,暗许backlog 值是50,十分轻易就满了。满了随后握手第三步的时候server就忽视了client发过来的ack包(隔意气风发段时间server重发握手第二步的syn ack包给client卡塔 尔(英语:State of Qatar),假设那几个接二连三平昔排不上队就那多少个了。

深入分析难题

$sudo ss -lnt

193 SYNs to LISTEN sockets dropped

总结

因为Nginx是多进度情势,也等于多少个经过都监听同一个端口以尽量幸免上下文切换到提高品质

试行表明下方面的精通

在大家的os中retry 第二步的私下认可次数是2(centos私下认可是5次卡塔 尔(英语:State of Qatar):

server4

紧接着查看溢出后,OS怎么处理:

51 SYNs to LISTEN sockets dropped

4.主次刚起步的时候必会现身部分,之后会间歇性出现。

16329 times the listen queue of a socket overflowed

一遍握手中,在第一步server收到client的syn后,把有关新闻放到半老是队列中,同不经常候复苏syn ack给client(第二步卡塔尔;

下边见到的第二列Send-Q 表示第三列的listen端口上的全连接队列最大为50,第一列Recv-Q为全连接队列当前利用了不怎么

LISTEN    0    511              *:8085          *:*

正规TCP建连接三回握手进程:

server1

(图片来自:http://www.cnxct.com/something-about-phpfpm-s-backlog/)

图片 11

比方syn floods 攻击正是针对性半连接行列的,攻击方不停地建连接,不过建连接的时候只做第一步,第二步中攻击方收到server的syn ack后故意扔掉什么也不做,导致server上那几个队列满别的正规伏乞不大概进去

if(sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_yong(sk)>1)

[root@server ~]# date; netstat -s | egrep "listen|LISTEN"

本文由时时app平台注册网站发布于时时app平台注册网站,转载请注明出处:关于TCP 半连接队列和全连接队列

关键词: