解决gatling端口占用问题
在使用gatling压测的过程中,经常会遇到 java.net.ConnectException: Cannot assign requested address这样的问题。这是由于端口不足引起的,一般情况下是TIME_WAIT链接太多导致的。 可以通过 ss -ant | awk '{++s[$1]} END {for(k in s) print k,s[k]}'(ss比netstat快很多)查看每个状态的链接数量。
TIME_WAIT状态
TCP是双向链接的,主动关闭的一方会进入TIME_WAIT状态。持续的时间一般在1~4分钟。我们来查看下本地端口的范围
1 2 3 4 5 6 |
sysctl -p net.ipv4.ip_local_port_range = 1024 65000 echo $((65000-1024)) 63976 |
也就6w多个。1000每秒的并发,1分钟就会产生6w左右了,这个端口范围是远远不够用的。我们需要限制TIME_WAIT的数量。
限制TIME_WAIT数量
一般我们会从net.ipv4.tcp_tw_recycle,net.ipv4.tcp_tw_reuse,net.ipv4.tcp_max_tw_buckets这几个内核参数入手。
- net.ipv4.tcp_tw_recycle: 回收TIME_WAIT连接。开启这个后,最快何时回收呢?在include/net/tcp.h可以看到
1 2 |
#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT * state, about 60 seconds */ |
也就是最快60s才能回收。通过上面的说明,开启这个并不会产生明显的效果。
- net.ipv4.tcp_tw_reuse:复用TIME_WAIT连接。当创建新连接的时候,如果可能的话会考虑复用相应的TIME_WAIT连接。重用TIME_WAIT的条件是收到最后一个包后超过1s。从解释中看,这个会对TIME_WAIT有明显的影响,但在实际情况中,开启这个还是解决不了问题。
上面的两个参数,必须要把net.ipv4.tcp_timestamps开启后才可以。否则不会生效。
- net.ipv4.tcp_max_tw_buckets:控制TIME_WAIT总数。这个产生了最明显的效果。官方的文档中建议不要减少此值。但在gatling的压测场景中,适当减少此值不会有任何的影响。在压测过程中,设置为 net.ipv4.tcp_max_tw_buckets=50000。
不错,不错,看看了!
看看!
年中快乐!
博客不错,嘎嘎!