TCP CLOSE_WAIT 과다 솔루션

위의 원인에 대한 분석:

1. 모두 개발된 솥이다


2. linux에서 CLOSE_WAIT 과다 해결 방법
상황 설명: 시스템에 대량의 "Too many open files"생성
원인 분석: 서버와 클라이언트가 통신하는 과정에서 서버에 socket이 꺼지지 않아 발생한closed_wait가 발생하여 감청 포트가 열린 핸들을 1024개로 세었고close_wait의 상태, 최종적으로 설정된 포트가 가득 차서 "Too many open files"가 나타나서 더 이상 통신할 수 없습니다.close_wait 상태가 나타나는 원인은 수동 폐쇄자가 socket을 닫지 않아서입니다.
해결 방법: 두 가지 조치가 있습니다. 하나, 해결:ServerSocket accept() Socket read() 를 호출할 때 스레드가 막히기 때문에 setSoTimeout() 로 시간 초과를 설정해야 하기 때문이다(부족한 설정은 0, 즉 시간 초과는 영원히 발생하지 않는다).시간 초과의 판단은 누적식이다. 한 번의 설정 후, 매번 호출로 인한 막힘 시간은 이 값에서 공제되며, 다른 시간 초과 설정이나 시간 초과 이상이 발생할 때까지.
예를 들어 어떤 서비스는read()를 세 번 호출하고 시간 초과를 1분으로 설정해야 한다. 만약에 어떤 서비스가read()를 세 번 호출하는 총 시간이 1분을 초과하면 이상이 발생한다. 같은 Socket에서 이런 서비스를 반복하려면 매번 서비스 전에 시간 초과를 설정해야 한다.
2. 회피:
핸들 관련 매개 변수와 TCP/IP 매개 변수를 포함한 시스템 매개 변수를 조정합니다.
참고:
/proc/sys/fs/file-max는 시스템 전체가 열 수 있는 파일 수의 제한으로sysctl에 의해 설정됩니다.conf 제어;
ulimit가 수정한 것은 현재 셸과 하위 프로세스가 열 수 있는 파일 수의 제한입니다. limits.conf 제어;
lsof는 시스템이 사용하는 자원을 열거하지만, 이 자원들이 반드시 파일 번호를 열 수 있는 것은 아니다.예를 들어 공유 메모리, 신호량, 메시지 대기열, 메모리 맵 등은 이런 자원을 차지하지만 파일 번호를 열지 않는다.
따라서 현재 사용자의 하위 프로세스가 열려 있는 파일 수의 제한, 즉 limits를 조정해야 합니다.conf 파일 설정;
만약cat/proc/sys/fs/file-max 값이 65536 또는 심지어 더 크면 이 값을 수정할 필요가 없습니다.
만약ulimit-a;그openfiles 매개 변수의 값은 4096(기본값은 1024)보다 작으면 다음과 같은 방법으로 openfiles 매개 변수의 값을 8192로 수정합니다.방법은 다음과 같습니다.
1. 루트 로그인을 사용하여 파일/etc/보안/limits를 수정합니다.conf
vim/etc/security/limits.conf
덧붙이다xxx - nofile 8192
xxx는 사용자입니다. 모든 사용자가 효력을 발휘하려면 *로 바꾸십시오. 설정된 수치는 하드웨어 설정과 관련이 있습니다. 너무 크게 설정하지 마십시오.
#               
*         soft    nofile    8192 
*         hard    nofile    8192

# 모든 사용자는 프로세스당 8192개의 파일 설명자를 사용할 수 있습니다.
2. 이러한 제한을 적용하기
파일/etc/pam을 확인합니다.d/login 및/etc/pam.d/sshd는 다음 행을 포함합니다.session required pam_limits.so
그리고 사용자가 다시 로그인하면 효력이 발생합니다.
  • bash에서 ulimit-a를 사용하여 수정되었는지 확인할 수 있습니다:
  • 1. 수정 방법: (잠시 효력이 발생하여 서버를 다시 시작하면 기본값으로 복원됩니다.)
    sysctl -w net.ipv4.tcp_keepalive_time=600 sysctl -w net.ipv4.tcp_keepalive_probes=2 sysctl -w net.ipv4.tcp_keepalive_intvl=2
    주의: Linux의 커널 파라미터가 합리적으로 조정되었는지 주의해서 관찰해야 하며, 업무의 절정기에 효과가 어떠한지 보아야 한다.
    2. 만약에 위에서 수정한 후에 작용할 수 있다.영구적으로 효력이 발생하도록 다음과 같이 수정한다.vi /etc/sysctl.conf
    구성 파일에 다음과 같은 정보가 없으면 다음을 추가합니다.
    net.ipv4.tcp_keepalive_time = 1800 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.tcp_keepalive_intvl = 15~~
    /etc/sysctl을 편집합니다.conf, 네트워크를 다시 시작해야 적용됩니다./etc/rc.d/init.d/network restart
    그리고sysctl 명령을 실행하면 수정이 효력을 발생합니다. 기본적으로 완성된 것입니다.
    수정 이유:
    클라이언트가 어떤 이유로 서비스 측보다 먼저 FIN 신호를 보내면 서비스 측이 수동적으로 닫힌다. 만약에 서비스 측이 소켓을 자발적으로 닫지 않으면 클라이언트에게 FIN을 보낸다. 이때 서비스 측 소켓은 CLOSE_WAIT 상태(LAST_ACK 상태가 아님).일반적으로 하나의 CLOSE_WAIT는 최소 2시간 동안 유지됩니다(시스템의 기본 시간 초과 시간은 7200초, 즉 2시간).만약 서버 프로그램이 어떤 원인으로 인해 시스템에 CLOSE_WAIT가 리소스를 소모하면 대개 방출 시점을 기다리지 못하면 시스템이 붕괴됩니다.따라서 이 문제를 해결하는 방법은 TCP/IP 파라미터를 수정하여 이 시간을 단축할 수 있기 때문에 tcpkeepalive* 시리즈 파라미터를 수정할 수 있다.
    tcp_keepalive_time:
    /proc/sys/net/ipv4/tcp_keepalive_time
    INTEGER, 기본값 7200(2시간)
    keepalive가 열려 있는 경우 TCP가 keepalive 메시지를 보내는 빈도수입니다.1800초로 수정하는 것이 좋습니다.
    tcp_keepalive_probes:INTEGER 
    
    /proc/sys/net/ipv4/tcp_keepalive_probes 

    INTEGER, 기본값은 9
    TCP는 연결이 끊어진 횟수를 확인하기 위해 keepalive 탐색을 보냅니다.(주의: 연결 유지는 SO_KEEPA LIVE 소켓 옵션이 열려 있는 경우에만 발송됩니다. 횟수는 기본적으로 수정할 필요가 없습니다. 물론 상황에 따라 이 값을 적당히 줄일 수 있습니다. 5로 설정하는 것이 적당합니다.)
    tcp_keepalive_intvl:INTEGER 
    
    /proc/sys/net/ipv4/tcp_keepalive_intvl 

    INTEGER, 기본값 75
    탐지가 확인되지 않았을 때, 탐지의 주파수를 다시 보냅니다.메시지 전송 주파수 탐지 (연결 실효를 인정하기 전에 TCP의keepalive 탐지 패키지를 몇 개 발송합니까).곱하기 tcp_keepalive_프로베스는 탐지를 시작한 이래 응답이 없는 연결을 제거하는 시간을 얻는다.기본값은 75초입니다. 즉, 활성화되지 않은 연결은 약 11분 후에 버려집니다.(일반 응용 프로그램에 있어서 이 값은 약간 커서 필요에 따라 줄일 수 있다. 특히 웹 서버는 이 값을 줄여야 한다. 15는 비교적 적합한 값이다)
  • 시스템에서 더 이상 오류 보고가 발생하지 않습니다.
  • TIME_WAIT 상태의 sockets는 길어지지 않습니다.

  • Linux에서 다음 구문을 사용하여 서버의 TCP 상태(연결 상태 수 통계)를 살펴봅니다.
    netstat -n| awk '/^tcp/{++S[$NF]} END {for(a in S) print a, S[a]}'

    좋은 웹페이지 즐겨찾기