socket带宽占用过高?

  • Post author:
  • Post category:其他


最近部署服务器集群的时候,查看了下原来单节点的配置,4核8G+8M带宽,跟领导申请是否需要保持配置,领导让根据实际情况调整下,尤其带宽部分,带宽太贵了主要是。

登录服务器之后,

top

下发现,cpu、内存占用并不高,

iftop -i eth0

,之后发现带宽占用居然有5M,检查在线人数发现,并没有太多。这个流量有4M来自某个ip,登录嫌疑ip服务器,检查端口占用情况:

netstat -antp | grep 1234

发现存在大量TIME_WAIT状态的连接,统计下有3w多。

常规情况下,通过调整内核参数解决


vi /etc/sysctl.conf

编辑文件,加入以下内容:

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

可惜我们的内核已经调整成该配置,问题仍然存在。

根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),TIME_WAIT状态下的socket不能被回收使用. 具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket, 甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务. TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证.

TCP结束的过程如下:

Server Client

————– FIN ————–> server: fin_wait_1

<————- ACK ————— client: close_wait server:fin_wait_2

<————- FIN ————— client发出fin之后就关闭

————– ACK ————-> server发出ack后进入time_wait状态

Time_Wait的默认时间是2倍的MLS,就是240秒钟。MLS是TCP片在网上的最长存活时间。

TIME_Wait的主要作用是保证关闭的TCP端口不立即被使用。因为当网络存在延迟时,可能当某个端口被关闭后,网络中还有一些重传的TCP片在发向这个端口,如果这个端口立即建立新的TCP连接,则可能会有影响。所以使用2倍的MSL时间来限制这个端口立即被使用。

这说明有大量的短连接没来得及回收,又产生了新的连接。

抓个包看看,1s抓了1M的数据。。。分析包发现,几乎都是3次握手,4次断开的,真正有用的数据不多。流量都是被这种无意义的包占满的,找同事确认逻辑之后,他是一个业务就需要发送几十个消息,所以才会占用如此多的带宽。

协商之后,让同事将接口调用改成了长连接。消息改走mns消息队列,带宽恢复正常。



版权声明:本文为qq_30164225原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。