서버 대량finuwait1 상태 장시간 존재 원인 분석
환경:
[root@localhost ~]# uname -aLinux localhost.localdomain 2.6.32-358.el6.x86_64
링크 상태는 다음과 같습니다.
ss -sTotal: 2753 (kernel 3336)TCP: 6046 (estab 730, closed 5001, orphaned 0, synrecv 0, timewait 5000/0), ports 564
Transport Total IP IPv6* 3336 - - RAW 1 1 0 UDP 599 599 0 TCP 1045 1037 8 INET 1645 1637 8 FRAG 0 0 0
[root@localhost ~]# ss -t state fin-wait-1
Recv-Q Send-Q Local Address:Port Peer Address:Port 0 384259 server_ip:serverport 10.231.18.150:44581 0 763099 server_ip:serverport 10.231.17.55:45202 0 543095 server_ip:serverport 10.231.22.76:35348 0 2379216 server_ip:serverport 10.231.22.37:56283 0 1237680 server_ip:serverport 10.231.17.161:48815 0 1720677 server_ip:serverport 10.231.16.73:51550 0 619159 server_ip:serverport 10.231.138.28:58986 0 474399 server_ip:serverport 10.231.18.82:45256 0 928420 server_ip:serverport 10.231.20.171:53326 0 27771 server_ip:serverport 10.231.138.38:58963 0 614664 server_ip:serverport 10.231.26.94:51083 0 152535 server_ip:serverport 10.231.19.184:43375
일부분만 붙입니다.
자세히 보면fin-wait-1의 송신 대기열에 일부 데이터가 대단에 전송되지 않은 것을 발견했습니다. 물론 사용자 상태close일 때 이런 상황은 허용되고 확인되지 않은 메시지 캐시입니다.
fin-wait-1 상태의 socket이 얼마나 많은 메모리를 차지하는지 보십시오.
ss -tn state fin-wait-1|grep -v Recv-Q|awk 'BEGIN{sum=0}{sum+=$2}END{printf "%.2f",sum}'221797627.00
점용이 많더라고요. 왜냐하면 이게 제가 tcp를 수정하고 있기 때문에.max_orphans가 아주 작은 상황에서만 점용하는 200여 M은 사실 내가 처리하지 않기 전에 점용하는 것이 16G에 달했다.
ss 안에 -m 옵션도 있고 socket의 메모리를 볼 수 있습니다. 하지만 저는 별로 사용하지 않습니다. 주로 다음과 같습니다.
if (tb[INET_DIAG_MEMINFO]) {
const struct inet_diag_meminfo *minfo
= RTA_DATA(tb[INET_DIAG_MEMINFO]);
printf(" mem:(r%u,w%u,f%u,t%u)",
minfo->idiag_rmem,
minfo->idiag_wmem,
minfo->idiag_fmem,
minfo->idiag_tmem);
예:
[root@ZSL-VS3000-3 ~]# ss -miten -o state last-ack|head -8
Recv-Q Send-Q Local Address:Port Peer Address:Port
1 7 49.115.46.140:60422 218.31.255.143:21 timer:(persist,097ms,1) ino:0 sk:ffff880d91cdd080
mem:(r0,w558,f3538,t0) sack cubic wscale:9,9 rto:202 rtt:2.625/1.75 ato:40 cwnd:1 ssthresh:7 send 4.4Mbps rcv_space:14600
0 51 49.115.46.140:21 110.157.1.10:54611 timer:(persist,147ms,1) ino:0 sk:ffff88140f9b0340
mem:(r0,w602,f3494,t0) sack cubic wscale:9,9 rto:213 rtt:13.625/10.25 ato:40 cwnd:1 ssthresh:7 send 857.2Kbps rcv_space:14600
0 51 49.115.46.140:21 110.157.2.9:59688 timer:(persist,174ms,1) ino:0 sk:ffff880560f88a40
mem:(r0,w602,f3494,t0) sack cubic wscale:9,9 rto:219 rtt:19.875/11.75 ato:40 cwnd:1 ssthresh:3 send 587.7Kbps rcv_space:14600
0 51 49.115.46.140:21 110.157.1.9:51252 timer:(persist,003ms,1) ino:0 sk:ffff88012d400d80
인터넷 검색, 대부분 수정 tcp_fin_timeout, 사실 이것은 FIN-WAIT-2를 겨냥한 것이다.
tcp_fin_timeout- INTEGER Time to hold socket in state FIN-WAIT-2, if it was closedby our side. Peer can be broken and never close its side,or even died unexpectedly. Default value is 60sec.Usual value used in 2.2 was 180 seconds, you may restoreit, but remember that if your machine is even underloaded WEB server, you risk to overflow memory with kilotons of dead sockets,FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,because they eat maximum 1.5K of memory, but they tendto live longer. Cf. tcp_max_orphans.
커널에서 TCP_FIN_WAIT1의 설정은 다음과 같습니다.
} else if (tcp_close_state(sk)) {/* We FIN if the application ate all the data before * zapping the connection. */
/* RED-PEN. Formally speaking, we have broken TCP state * machine. State transitions: * * TCP_ESTABLISHED -> TCP_FIN_WAIT1 * TCP_SYN_RECV -> TCP_FIN_WAIT1 (forget it, it's impossible) * TCP_CLOSE_WAIT -> TCP_LAST_ACK * * are legal only when FIN has been sent (i.e. in window), * rather than queued out of window. Purists blame. * * F.e. "RFC state"is ESTABLISHED, * if Linux state is FIN-WAIT-1, but FIN is still not sent. * * The visible declinations are that sometimes * we enter time-wait state, when it is not required really * (harmless), do not send active resets, when they are * required by specs (TCP_ESTABLISHED, TCP_CLOSE_WAIT, when * they look as CLOSING or LAST_ACK for Linux) * Probably, I missed some more holelets. * --ANK */tcp_send_fin(sk);
즉, fin-wait-1 상태를 설정한 다음fin 패키지를 보내고,
이론적으로 말하자면fin-wait-1의 상태는 보기 어려울 것이다. 왜냐하면 상대방의ack만 받으면 fin-wait-2로 옮겨야 하기 때문이다. 만약에 상대방의fin을 받으면 옮겨야 한다.
closing 상태.근데 이 서버에 많아요.혹시 ack이나 fin 가방 못 받았어요?패키지 확인 아래:
더 나아가 클러치, tcpdump-i eth0"tcp[tcpflags] & (tcp-fin)! = 0"-s 90-p-n
메시지에 따르면 핀백의 재전송을 보았는데 때때로 대단 알림 창이 0이기 때문에fin-wait-1에 들어간 후 머무르는 시간이 비교적 길다.
예를 들어fin-wait-1을 보면 그 후의 상호작용 가방을 잡을 수 있고,
[root@localhost~] #ss-tostate Fin-wait-1 |head-200 |grep-i 10.96.152.2190 387543 서버 ip 클라이언트 ip 1 timer: (persist, 1.140ms, 0) 여기서 우리는 타이머를 견지하는 것을 보았다. 스크립트를 통해 나는fin-wait-1의 체인을 얻었다. 어떤 타이머의 길이는 회피한 후에 120s에 이르렀고 120s까지 탐지했다.
여기서 스크립트의 사고방식을 말해 보세요.
#!/bin/bashwhile [1]do ss-tn state Fin-wait-1 src 서버 ip | awk'{print $4}'|grep-v 서버 포트 1|grep-v 서버 포트 2|sort-n>caq_old ss-tn state Fin-wait-1 src 서버 ip | awk'{print $4}'|grep-v 서버 포트 1|grep-v 서버 포트 1|sort-n>caq_new diff caq_old caq_new|grep '>'|awk '{print $2}' >diff_caq sleep 1
###1s 이후fin-wait-1 상태의 체인 상황을 다시 가져옵니다. 추가된 체인이 존재한다면 이 체인은 최소 1s 이상 생존할 수 있습니다. 주로 타이머가 비교적 긴 상태를 유지하는 ss-tnstate Fin-wait-1 src 서버 ip|awk'{print $4}'|grep-v 서버 포트 1|grep-v 서버 포트 2|sort-n>caq_new while read line do grep -q $line caq_new if [ $? -eq 0 ] then ###live for 1 second echo $line exit else continue; fi done < diff_caq
done
그리고 가방을 잡으세요.
./get_fin.sh |awk -F '[:]' '{print $2}'|xargs -t tcpdump -i eth1 -s 90 -c 200 -p -n port
일부 클러치가 보입니다.
20:34:26.355115 IP 서버 ip 및 포트 > 클라이언트 ip 및 포트: Flags [.],ack 785942062, win 123, length 020:34:26.358210 IP 클라이언트 ip 및 포트 > 서버 ip 및 포트: Flags [.],ack 1, win 0, length 020:34:28.159117 IP 서버 ip 및 포트 > 클라이언트 ip 및 포트: Flags [.],ack 1, win 123, length 020:34:28.162169 IP 클라이언트 ip 및 포트 > 서버 ip 및 포트: Flags [.],ack 1, win 0, length 020:34:31.761502 IP 서버 ip 및 포트 > 클라이언트 ip 및 포트: Flags [.],ack 1, win 123, length 020:34:31.765416 IP 클라이언트 ip 및 포트 > 서버 ip 및 포트: Flags [.],ack 1, win 0, length 0
다음으로 전송:https://www.cnblogs.com/10087622blog/p/7281883.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.