近期数据库慢,发现会话有1万个,考虑到128个CPU,1万个线程肯定是过载了。
1.定位出这1万个会话是从哪里连进来的,查了一下会话IP居然是unknown的,不知道是从哪里发起的。
从操作系统层面上,netstat -tpna看tcp连接是从应用服务器连过来的。
2.需要定位出应用服务器上哪个程序产生的,netstat -tpna | grep 1111 ,(YY:1111是数据库的IP和端口)有1千多个tcp连接,
并没有发现进程。
tcp 0 0 XX:56678 YY:1111 FIN_WAIT2 -
tcp 0 0 XX:32816 YY:1111 FIN_WAIT2 -
tcp 0 0 XX:52104 YY:1111 FIN_WAIT2 -
tcp 0 0 XX:46242 YY:1111 FIN_WAIT2 -
tcp 0 0 XX:49040 YY:1111 FIN_WAIT2 -
tcp 0 0 XX:47846 YY:1111 FIN_WAIT2 -
tcp 0 0 XX:59486 YY:1111 FIN_WAIT2 -
tcp 0 0 XX:46534 YY:1111 FIN_WAIT2 -
3.在应用和数据库服务器上抓包tcpdump,想确认是什么功能在频繁做tcp连接。分析结果大失所望,应用服务器上连接过来之后做
三次握手,然后四次挥手,还没来得及晚上挥手服务端就把连接RST了。换言之,连接啥也没干。
4.虽然tcpdump看来是一无所获,不过还是有点收获的,感觉是一个心跳检测。确认心跳检测100ms检测一次,如果不通,重复1前次。
5.屏蔽掉心跳检测的程序,数据库会话正常。
6.原本找不出来问题,调整网络参数,不过这种调整治标不治本。
//复用即将关闭的端口
net.ipv4.tcp_tw_reuse = 1
//要想上面的生效,需要配置下面的参数
net.ipv4.tcp_timestamps=1
总结:本次的问题是心跳检测太过于频繁,600多个应用节点,100ms检测一次,1秒钟会检测6000次,当网络发生抖动,大量tcp连接数据库服务器,它是无法应对。