IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> ab压测Http Server时TCP连接TIME_WAIT状态研究 -> 正文阅读

[网络协议]ab压测Http Server时TCP连接TIME_WAIT状态研究

当ab压测工具和http server在同一台(centos)机器时,为何不会出现端口不够用的情况呢?

假设压测参数如下:
ab -n100000 -c5000 http://localhost/a.php
  • 我们都知道tcp有四元组的概念,server_ip:server_port <=> client_ip:client_port,对于server端,只需要一个固定端口,而client端每个连接需要使用不同的随机端口,在linux下随机端口是有限的,执行命令查看:
    cat /proc/sys/net/ipv4/ip_local_port_range
    ,默认一般是32768~60999,也就是说只有2.8w+左右的随机可用端口数,
  • 现在开始分析,上述ab压测不加keep-alive(-k)参数,则是短连接的情况,此时由http server主动close连接,所以这时产生的大量TIME_WAIT 也只是影响http client端,因为http server端永远只需要一个80端口,所以对于server端来说,不需要担心端口数耗尽的问题。但是问题来了,ab和http_server在同一台的,ab压测时的http client是需要使用随机端口的,按照上述5000并发,而time_wait存在时长大约是1分钟左右,那么30秒内就可以产生15万个短连接,如果这些短连接很快就执行结束,那么1分钟内至少可以产生10万个time_wait状态的连接,也就是需要10万个本地随机端口,按理说ab应该报错退出了,可是压测的时候使用如下命令:netstat -anp | grep 'TIME_WAIT' | wc -l 会发现time_wait的数量到16384以后就上不去了。why???

其实是linux对本地随机端口数超过上限有个保护策略,在/etc/sysctl.conf中修改:
net.ipv4.tcp_max_tw_buckets = 16384 这个值,即TIME_WAIT连接数超过这个阈值时,linux会直接
关闭并清除这个连接,所以ab压测不会太轻易的就出现端口数不够用的情况,当你把net.ipv4.tcp_max_tw_buckets改的够大,net.ipv4.ip_local_port_range改小一些,就会发现ab报错:
cannot assign requested address

为何time_wait 必须存在呢?
  • 查阅关于tcp四次挥手的资料,可以看到说明,此处只想浓缩成一句话:

tcp主动关闭端为了保证tcp被动关闭端,能收到最后一个ACK。(让子弹飞一会)

  • 我们举个例子:你使用公共电话和114客服中心打电话,最后你要说的都说完了,你准备挂电话(主从close连接,产生TIME_WAIT),如下:

你说: 我要挂电话了,
对方:好的,感谢你的来电。请问还有什么问题吗?
你说:没了

这个“没了”就是最后一个ACK
,因为你素质比较高,你要确保对方收到“没了”这个ACK。就是你要等一会直到听到对方挂断电话(嘟嘟嘟)的声音,这个等待的时间就是一个MSL(MSL就是一个tcp包在网络上最长可存在的时间,打个比方,某句话是昨天说的话,今天才收到,那就是可以忽略的数据),一个MSL在linux上是1分钟。
如果没有time_wait,也就是你素质不想那么高,当对方说:好的,感谢你的来电。请问还有什么问题吗?你刚说:没了,立马挂机,假设这时候信号不好,对方可能还没听到 “没了” 或者最后这个ACK丢了,那对方等待一会之后,肯定会以为你还在,会再次问你:“好的,感谢你的来电。请问还有什么问题吗?” 结果对面传来 “嘟嘟嘟” 挂机的声音。这个类似收到tcp RST了。然后客服无奈也挂机了。四次挥手就这样不太愉快的结束了。

  • 上述情况只是没有并发的情况,实际情况是,一个公共电话坐机就相当于一个linux本地端口号,由于端口号是有限的资源,所以是不断的复用,就好比N台公共电话亭,提供给大量的用户使用,如果一个用户没有完整的通话结束,其他客户端复用这个电话机的时候,就有可能收到上一个用户的数据,比如上述的情况,用户A对客服说 “没了” 之后立即挂断,然后用户B马上复用这个线路,就有可能收到客服的消息:“好的,感谢你的来电。请问还有什么问题吗?” 此时用户B肯定问号脸,什么情况?

总结:

time_wait就是为了四次挥手正确的完成,保证前后复用同一个端口的连接之间数据没有错乱的情况发生。

再来一次特殊的压测: (ab和http_server同一台机器)
  • ab压测命令如下:
ab -n1 -c1 http://localhost/a.php
  • tcp内核参数调整如下
net.ipv4.tcp_max_tw_buckets = 1638400 //该配置说明tw_buckets足够大,基本不会出发快速回收清除
net.ipv4.ip_local_port_range=60999 61000 //该配置说明,只有60999和61000两个端口可用
net.ipv4.tcp_tw_recycle =0
net.ipv4.tcp_tw_reuse =0

根据上述的配置和压测参数,执行第三轮压测的时候,ab应该要报错:cannot assign requested address, 但是结果却是第6轮之后都不报错,为啥????

  • 当ab压测加上-k参数时:ab -n1 -c1 -k http://localhost/a.php , 会发现第三次的时候,ab会因端口数不够而报错:annot assign requested address。这个结果和预期想法时一致的。(time_wait会持续1分钟,一分钟内执行三次压测,就会端口数不够用而报错)
现在开始分析ab不加-k参数:ab -n1 -c1 http://localhost/a.php为何不会因为端口不够用而报错?

不加-k,连接由server端主动关闭,即time_wait状态属于服务器的。当压测过程中执行: netstat -anp | grep 80 应该有两条结果 :
127.0.0.1:80 127.0.0.1:61000 established
127.0.0.1:61000 127.0.0.1:80 established
但是因为ab压测并发才1,很快就结束,意味着tcp established状态压测结束就立即消失了,所以压测完成执行netstat命令应该只能看到一条:
127.0.0.1:80 127.0.0.1:61000 TIME_WAIT
我们看一下ip:port的显示顺序,从左到右是:127.0.0.1:80 -> 127.0.0.1:61000, 表示http server端主从close连接产生了TIME_WAIT状态,而对于ab压测客户端而言,从61000 -> 80 端口的tcp状态会经历从established -> close_wait -> last_ack -> closed 而这个状态变化过程很快就结束,所以对ab客户端而言,61000这个端口马上又可以用了,而对server端来说80 -> 61000的time_wait会存在>=1分钟, 当ab压测再次用到61000这个端口时,对于server端而言的tcp连接状态会从time_wait 马上更新成establshed状态,即:127.0.0.1:80 127.0.0.1:61000 established,虽然tcp四元组看起来和上次一样,但是连接已经是新创建的了。

总结:ab不加-k是server端产生time_wait状态,ab客户端处于close_wait状态很快就结束,使得ab客户端马上有端口可用( 因server端只需要80端口,不会占用本地随机端口),tcp的本地随机端口本来就像连接池一样,重复利用的,两次压测虽然tcp四元组一样,但是连接已经是新创建的了,。

加深对总结的理解技巧
  • 理解方式1:

(针对client和server是一台机器的情况),可以把server端想象成银行服务台,始终在一个固定的窗口(理解成http 80端口)提供服务,每次客户需要服务,都拿小票过来(小票上的号码理解成本地随机端口号), 而小票上的数字都是重1-1000 反复循环使用,对于同一个四元组(中国银行:80号服务窗口号,中国银行:61000小票号码), 服务的人可能就是不同的人了。

  • 理解方式2:

server端只需要80端口,client端从本地端口池(net.ipv4.ip_local_port_range中指定的)中获取一个可用端口,当第一次ab压测结束时,61000端口因处于close_wait很快就把端口号归还端口池,所以第二次压测时,依旧有端口号可用。对server端来说,TIME_WAIT状态只是确保客户端连接的最后一个ACK能收到,如果同一个host主机同一个端口在极短时间内创建两个连接,还是有概率客户端收到RST的,现象就是connection reset by peer,这种是最后一个ACK丢包的情况,概率比较低

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-07-13 17:51:11  更:2021-07-13 17:51:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 17:28:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码