1、首先你要明白KeepAlive到底是什么东西?其次你要了解KeepAlive在压测过程中会造成哪些影响?
我们要对keepalive有个简易的理解:TCP的keep alive是检查当前TCP连接是否活着;HTTP的Keep-alive是要让一个TCP连接活久点;在一个TCP连接内,多个HTTP请求可以并行,下一个HTTP请求在上一个HTTP请求的应答完成之前就发起。它们是不同层次的概念,所以叫http长连接似乎是不太合理的,应该叫多个http请求时的tcp长连接复用。
那我们可能会想,当我们在使用jmeter并发测试的时候,如果勾选了keep-alive,是不是走的都是重复的连接,即并发数和客户端的端口数应该是一样的。但并不是这个样子。
jmeter在发送http请求时,默认带有keep-alive,但我们通过查看jmeter配置文件发现并没有相关有效的连接时长配置,可以认定:jmeter中的请求都是无等待请求,response time约等于零,一旦连接数据接收完毕,或者接口处于空闲状态,连接便会断开
所以在不修改jmeter默认配置情况下,每个线程都是独立的、全新的,无论是否勾选keep-alive,请求都不受影响(服务端强制要求短连接除外)
在详细了解TCP连接的状态和关闭方式后,我们会发现TIME_WAIT状态是一个坑爹的存在!主动关闭连接的一方在发送最后一个ACK包后,无论对方是否收到都会进入TIME_WAIT状态,等待2MSL的时间,然后才能释放网络资源。MSL就是Maximum Segment Lifetime(数据包的最大生命周期),是一个数据包能在互联网上生存的最长时间,若超过这个时间则该数据包将会消失在网络中。操作系统通常会将2MSL设为4分钟,最低不少于30秒,因而TIME_WAIT状态一般维持在30秒至4分钟;
对于Client而言,每个连接都需要占用一个端口,而系统允许的可用端口数不足65000个(这也是在TCP参数优化后才能达到)。因此,如果Client发起过多的连接且连接未关闭,就会有大量的连接处于TIME_WAIT状态,等待2MSL的时间后才能释放端口,于是Client会由于缺少可用端口而无法新建连接。
[time_wait端口查询 netstat -aon|findstr "TIME_WAIT"]
1.增加系统端口
我们可以通过修改注册表配置来解决问题:
1,启动注册表编辑器(Regedt32.exe )。
2,在注册表中确定下述键值的位置:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
在“编辑”菜单上点击“添加值”,然后增加下述注册值:
Value Name: MaxUserPort
Data Type: REG_DWORD
Value: 65534
它用于设置为任何用户提供的临时端口数。有效范围介于5000 和65534 之间(十进制)。默认值为0x1388 (5000 ,十进制)。
3,在“编辑”菜单上点击“添加值”,然后增加下述注册值:
Value Name: TcpTimedWaitDelay
Data Type: REG_DWORD
Value: 30
它用于设置关闭之前将TCP 端口连接保持在TIME_WAIT 状态的秒数。 有效范围介于0 秒和300 秒之间。默认值为0x78 (120 秒)。
4,退出注册表编辑器。
5,重启服务器。
2.windows修改句柄文件
Windows 下单机的TCP连接数有多个参数共同决定
最大TCP连接数
[HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters]
TcpNumConnections = 0x00fffffe (Default = 16,777,214)
以上注册表信息配置单机的最大允许的TCP连接数,默认为 16M。这个数值看似很大,这个并不是限制最大连接数的唯一条件,还有其他条件会限制到TCP 连接的最大连接数。
最大动态端口数
TCP客户端和服务器连接时,客户端必须分配一个动态端口,默认情况下这个动态端口的分配范围为 1024-5000 ,也就是说默认情况下,客户端最多可以同时发起3977 个Socket 连接。我们可以修改如下注册表来调整这个动态端口的范围
[HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters]
MaxUserPort = 5000 (Default = 5000, Max = 65534)
最大TCB 数量
系统为每个TCP 连接分配一个TCP 控制块(TCP control block or TCB),这个控制块用于缓存TCP连接的一些参数,每个TCB需要分配 0.5 KB的pagepool 和 0.5KB 的Non-pagepool,也就说,每个TCP连接会占用 1KB 的系统内存。
系统的最大TCB数量由如下注册表设置决定
[HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters]
MaxFreeTcbs = 2000 (Default = RAM dependent, but usual Pro = 1000, Srv=2000)
MaxFreeTcbs 的默认值为1000 (64M 以上物理内存)
最大TCB Hash table 数量
TCB 是通过Hash table 来管理的,下面注册表设置决定了这个Hash table 的大小
HKEY_LOCAL_MACHINE \System \CurrentControlSet \services \Tcpip \Parameters]
MaxHashTableSize = 512 (Default = 512, Range = 64-65536)
这个值指明分配 pagepool 内存的数量,也就是说,如果MaxFreeTcbs = 1000 , 则 pagepool 的内存数量为 500KB
那么 MaxHashTableSize 应大于 500 才行。这个数量越大,则Hash table 的冗余度就越高,每次分配和查找 TCP 连接用时就越少。这个值必须是2的幂,且最大为65536.
IBM WebSphere Voice Server 在windows server 2003 下的典型配置
这是IBM WebSphere Voice Server 的典型配置,大家可以做个参考。原文参见
[IBM WebSphere Voice Server 在windows server 2003 下的典型配置]
MaxUserPort = 65534 (Decimal)
MaxHashTableSize = 65536 (Decimal)
MaxFreeTcbs = 16000 (Decimal)
这里我们可以看到 MaxHashTableSize 被配置为比MaxFreeTcbs 大4倍,这样可以大大增加TCP建立的速度。
3.单网卡捆绑多ip
一次偶然机会,从朋友那里听到什么东东能支持单台机器“上百万并发量”,于是考虑如何解决tcp客户端端口不够的问题。
因为默认65535端口,经过设置,最多端口数不到60000,如何能达到百万呢?
看了下UNP,里面讲SO_REUSEADDR应用的4种场景时有说到:
SO_REUSEADDR允许单个进程捆绑同一端口到多个套接字上,只要每次捆绑指定不同的贝蒂IP地址即可。
于是猜测:当某个IP的端口用尽时可以选择另一个IP进行发送消息。
那么如何在一个机器上虚拟出多个ip地址呢?
可以使用工具ipop
工具下载地址:链接:https://pan.baidu.com/s/12lqGqyFsvxJ1NEVsS4eW5g 提取码:6666