文章插图
作者 | 小林coding
来源 | 小林coding
责编 | 王晓曼
文章插图
前言
网上许多博客针对增大 TCP 半连接队列和全连接队列的方式如下:
- 增大 TCP 半连接队列方式是增大 tcp_max_syn_backlog;
- 增大 TCP 全连接队列方式是增大 listen 函数中的 backlog;
“你怎么知道不准确?”
很简单呀,因为我做了实验和看了 TCP 协议栈的内核源码,发现要增大这两个队列长度,不是简简单单增大某一个参数就可以的 。
接下来,就会以实战+源码分析,带大家解密 TCP 半连接队列和全连接队列 。
“源码分析,那不是劝退吗?我们搞 JAVA 的看不懂呀”
放心,本文的源码分析不会涉及很深的知识,因为都被我删减了,你只需要会条件判断语句 if、左移右移操作符、加减法等基本语法,就可以看懂 。
另外,不仅有源码分析,还会介绍 linux 排查半连接队列和全连接队列的命令 。
“哦?似乎很有看头,那我姑且看一下吧!”
文章插图
什么是 TCP 半连接队列和全连接队列?
在 TCP 三次握手的时候,Linux 内核会维护两个队列,分别是:
- 半连接队列,也称 SYN 队列;
- 全连接队列,也称 accepet 队列;
文章插图
半连接队列与全连接队列
不管是半连接队列还是全连接队列,都有最大长度限制,超过限制时,内核会直接丢弃,或返回 RST 包 。
文章插图
实战 - TCP 全连接队列溢出
1、如何知道应用程序的 TCP 全连接队列大小?
在服务端可以使用 ss 命令,来查看 TCP 全连接队列的情况:
但需要注意的是 ss 命令获取的 Recv-Q/Send-Q 在「LISTEN 状态」和「非 LISTEN 状态」所表达的含义是不同的 。从下面的内核代码可以看出区别:
文章插图
在「LISTEN 状态」时,Recv-Q/Send-Q 表示的含义如下:
文章插图
- Recv-Q:当前全连接队列的大小,也就是当前已完成三次握手并等待服务端accept 的 TCP 连接个数;
- Send-Q:当前全连接最大队列长度,上面的输出结果说明监听 8088 端口的 TCP 服务进程,最大全连接长度为 128;
文章插图
- Recv-Q:已收到但未被应用进程读取的字节数;
- Send-Q:已发送但未收到确认的字节数;
文章插图
测试环境
实验环境:
- 客户端和服务端都是 centos 6.5 ,Linux 内核版本 2.6.32
- 服务端 IP 192.168.3.200,客户端 IP 192.168.3.100
- 服务端是 Nginx 服务,端口为 8088
本次模拟实验就使用 wrk 工具来压力测试服务端,发起大量的请求,一起看看服务端 TCP 全连接队列满了会发生什么?有什么观察指标?
客户端执行 wrk 命令对服务端发起压力测试,并发 3 万个连接:
文章插图
在服务端可以使用 ss 命令,来查看当前 TCP 全连接队列的情况:
文章插图
其间共执行了两次 ss 命令,从上面的输出结果,可以发现当前 TCP 全连接队列上升到了 129 大小,超过了最大 TCP 全连接队列 。
推荐阅读
- 司机高速上睡了半小时,车内“无人驾驶”48公里,让人无法相信
- 茶树的形状乔木型,半乔木型茶树先容
- 下半身减肥运动有什么?
- 无线网络连接怎么设置
- httpclient连接池管理,你用对了?
- 发酵茶怎么发酵,生普属于半发酵茶么
- 说起来 TCP 的连接与释放真是个浪漫的故事呢!
- Win10电脑蓝牙连接手机播放音乐
- 东半山忙蚌普洱茶介绍,忙蚌茶区
- 春天喝什么茶?茶叶入菜香自来!