대량 TIME 출현WAIT 연결 검사 및 해결

5807 단어 php-fpmnginx
Last - Modified: 2019 년 7 월 10 일 21: 58: 43
프로젝트 생산 환경 대량 TIME 출현WAIT (수천 개), 일일이 조사 필요
먼저 정리:
  • nginx 가 keep - alive 를 열지 않 아 대량의 주동 적 으로 끊 긴 tcp 연결
  • nginx 와 fastcgi (pp - fpm) 의 연결 은 기본적으로 짧 은 연결 입 니 다. 이때 TIME 가 나타 납 니 다.WAIT

  • 상태 확인
    통계 TIMEWAIT 연 결 된 로 컬 주소
    netstat -an | grep TIME_WAIT | awk '{print $4}' | sort | uniq -c | sort -n -k1
    
    #    ...        
    #    2 127.0.0.1:56420
    #    442 192.168.1.213:8080
    #    453 127.0.0.1:9000

    분석:
  • 8080 포트 는 nginx 대외 포트
  • 9000 포트 는 pp - fpm 포트
  • 8080 대외 웹 포트
    nginx 설정 파일 에 한 줄 이 있 는 지 확인 하 십시오.
    #     keep-alive
    keepalive_timeout 0;

    tcp 패키지 캡 처 시도
    tcpdump tcp -i any -nn port 8080 | grep "  ip"
    
    #             
    # 20:52:54.647907 IP    .6470 >    .8080: Flags [S], seq 2369523978, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
    # 20:52:54.647912 IP    .8080 >    .6470: Flags [S.], seq 1109598671, ack 2369523979, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
    # 20:52:54.670302 IP    .6470 >    .8080: Flags [.], ack 1, win 256, length 0
    # 20:52:54.680784 IP    .6470 >    .8080: Flags [P.], seq 1:301, ack 1, win 256, length 300
    # 20:52:54.680789 IP    .8080 >    .6470: Flags [.], ack 301, win 123, length 0
    # 20:52:54.702935 IP    .8080 >    .6470: Flags [P.], seq 1:544, ack 301, win 123, length 543
    # 20:52:54.702941 IP    .8080 >    .6470: Flags [F.], seq 544, ack 301, win 123, length 0
    # 20:52:54.726494 IP    .6470 >    .8080: Flags [.], ack 545, win 254, length 0
    # 20:52:54.726499 IP    .6470 >    .8080: Flags [F.], seq 301, ack 545, win 254, length 0
    # 20:52:54.726501 IP    .8080 >    .6470: Flags [.], ack 302, win 123, length 0

    상술 한 구체 적 인 ip 은 이미 나 에 의 해 대량으로 교체 되 어 서버 ip 노출 이 불편 하 다.
    분석:
  • 손 을 네 번 흔 드 는 시작 이 서버 에서 주동 적 으로 시 작 된 것 을 볼 수 있다 (TIME WAIT 는 주동 적 으로 연결 을 끊 는 쪽 에 만 나타 난 다 는 것 을 기억 하 라)
  • 개인 적 으로 nginx 는 "keep - alive 를 사용 하지 않 음" 을 설정 할 때 http 요청 이 끝 날 때 자발적으로 연결 을 끊 는 다 는 것 을 이해 합 니 다.
  • http 의 keep - alive
  • 를 켜 려 고 시도 합 니 다.
    nginx 설정 수정
    keepalive_timeout 65;

    reload nginx
    nginx -s reload

    다시 가방 을 잡다
    tcpdump tcp -i any -nn port 8080 | grep "  ip"
    
    # 21:09:10.044918 IP    .8217 >    .8080: Flags [S], seq 1499308169, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
    # 21:09:10.044927 IP    .8080 >    .8217: Flags [S.], seq 2960381462, ack 1499308170, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
    # 21:09:10.070694 IP    .8217 >    .8080: Flags [.], ack 1, win 256, length 0
    # 21:09:10.077437 IP    .8217 >    .8080: Flags [P.], seq 1:302, ack 1, win 256, length 301
    # 21:09:10.077443 IP    .8080 >    .8217: Flags [.], ack 302, win 123, length 0
    # 21:09:10.198117 IP    .8080 >    .8217: Flags [P.], seq 1:671, ack 302, win 123, length 670
    # 21:09:10.222957 IP    .8217 >    .8080: Flags [F.], seq 302, ack 671, win 254, length 0
    # 21:09:10.222980 IP    .8080 >    .8217: Flags [F.], seq 671, ack 303, win 123, length 0
    # 21:09:10.247678 IP    .8217 >    .8080: Flags [.], ack 672, win 254, length 0

    위 에 재 미 있 는 곳 을 잘 보 세 요.
  • tcp 의 흔 들 림 은 정상 적 인 4 번 이 아니 라 3 번 에 불과 합 니 다. 개인 적 으로 는 서버 가 FIN 을 받 았 을 때 데 이 터 를 다시 보 내지 않 는 다 는 것 을 확 인 했 기 때문에 FIN 을 ACK 와 함께 합 쳐 보 냅 니 다
  • .
  • 클 라 이언 트 가 tcp 연결 을 자발적으로 끊 었 기 때문에 서버 에 TIME 가 나타 나 지 않 습 니 다.WAIT

  • 연결 상태 다시 보기
    netstat -an | grep TIME_WAIT | awk '{print $4}' | sort | uniq -c | sort -n -k1
    #      ...    
    #      1 127.0.0.1:60602
    #      1 127.0.0.1:60604
    #    344 127.0.0.1:9000

    이 때 이미 TIMEWAIT 연결 되 었 습 니 다.
    9000 fast - cgi 포트
    인터넷 을 통 해 자 료 를 찾 고 정리 합 니 다.
  • nginx 와 fast - cgi 의 기본 연결 은 짧 은 연결 입 니 다. 연결 할 때마다 완전한 tcp 연결 과 끊 기
  • 를 거 쳐 야 합 니 다.
    현재 nginx 설정
    upstream phpserver{
        server 127.0.0.1:9000 weight=1;
    }

    nginx 설정 을 수정 하여 fastcgi 와 의 연결 을 긴 연결 로 사용 합 니 다.
    upstream phpserver{
        server 127.0.0.1:9000 weight=1;
        keepalive 100
    }
    
    fastcgi_keep_conn on;

    설명:
  • upstream 에 있 는 keepalive nginx 의 모든 worker 와 fastcgi 의 최대 긴 연결 수 를 지정 합 니 다. 긴 연결 이 부족 할 때 새로 만 든 연결 은 요청 이 끝 난 후에 끊 깁 니 다. (이때 HTTP 1.1 이 지정 되 어 있 기 때문에 fastcgi 가 자발적으로 연결 을 끊 지 않 기 때문에 nginx 쪽 에 TIME WAIT 가 대량으로 나타 날 수 있 습 니 다. 신중 (검증 되 지 않 음)
  • php - fpm 에 최대 프로 세 스 수가 100 으로 설정 되 어 있 기 때문에 이 곳 의 keepalive 수량 은 100 (테스트 되 지 않 음)
  • 을 지정 합 니 다.
    이 문 제 는 nginx 가 역방향 에이전트 라면 다음 설정 을 추가 해 야 합 니 다.
    #  http   1.0   1.1
    proxy_http_version 1.1;
    #   "Connection"  
    proxy_set_header Connection "";    
  • 설정 proxy_pass 백 엔 드 에 전송 요청
  • 여기, 이해 해 주세요 proxy_passfastcgi_pass 의 차이 점
        --http-->        Nginx --proxy_pass-->      Nginx --fastcgi_pass-->       php-fpm
  • tcp 연결 상황 재 확인
    netstat -antp  | grep :9000 | awk '{print $(NF-1)}' | sort | uniq -c
    #      6 ESTABLISHED
    #      1 LISTEN
    

    ok, 문제 해결.
    다른 해결 방법:
    nginx 와 fast - cgi 가 같은 서버 에 있 으 면 유 닉 스 도 메 인 을 사용 하면 더욱 효율 적 이 고 TIME WAIT 문 제 를 피 할 수 있 습 니 다.
    주제 밖
    위의 최 적 화 를 거 친 후에 TIME WAIT 수량 은 수천 개 에서 수 십 개 로 대폭 줄 어 들 었 다. 이때 TIME WAIT 에 대량의 127.0.0.1: 6379 가 redis 서비스의 기본 포트 라 는 것 을 발견 했다.
    업무 코드 를 빨리 바 꾸 고 $redis->connect(...)$redis->pconnect(...) 로 바 꾸 세 요.
    설명:
  • pconnect php - fpm 와 redis 가 tcp 연결 을 한 후에 도 이번 http 요청 이 끝 난 후에 도 이 연결 을 유지 합 니 다. 다음 에 새로운 요청 이 들 어 올 때 이 연결 을 재 활용 하여 tcp 연결 을 재 활용 할 수 있 습 니 다.
  • 좋은 웹페이지 즐겨찾기