close connection error java.sql.SQLRecoverableException: IO Error: Broken pipe

4757 단어

 java.sql.SQLRecoverableException: IO Error: Broken pipe


Table of Contents

  • 1. 오류 메시지
  • 2. 분석
  • 2.1. 연못을 연결하다
  • 2.2. TCP 네트워크
  • 2.3. 데이터베이스 감청


  • 1 오류 정보

    ERROR [com.alibaba.druid.util.JdbcUtils] - close connection error
    java.sql.SQLRecoverableException: IO Error: Broken pipe
    

    2 분석


    이 문제에 부딪히면 일반적으로 프로그램 접근 서비스(예를 들어 데이터베이스)에 부딪힌다.이 사이에는 여러 개의 네트워크 통신 노드가 존재한다.
    프로그램 – > 접속 풀 – > 네트워크 카드 – > 방화벽 – > 라우터 – > 방화벽 – > 서버 네트워크 카드 – > 서버 정적 라우팅 – > 서버 방화벽 – > 서비스 모니터링 – > 서비스
    프로그램과 연결 탱크(일반적으로 통합된 것)를 제외하고 다른 모든 노드가 연결을 끊으면 이 문제, 특히 방화벽을 일으킬 수 있다.일반적으로 어떤 연결을 끊는 원인은 이 연결이 너무 오랫동안 비어 있기 때문이다.네트워크 방화벽, tcp 네트워크, 서버 로컬 방화벽, 감청 이 몇 개의 노드에 빈 연결 제어가 있습니다.
    다음은 연결 탱크, 서버의 tcp 네트워크, 데이터베이스 차원을 설정하여 빈 연결이 이상하게 중단되는 문제를 해결합니다.

    2.1 연결 풀


    현재 국내에서는 대부분druid를 프로그램의 연결 탱크로 사용한다.그러면 이 연결 탱크는 빈 연결에 대해 검측과 검사 메커니즘을 제공한다.예를 들어 이 연결을 사용할 것을 신청할 때 이 연결이 사용할 수 있는지 테스트하고, 빈 연결이 사용할 수 있는지 확인하고, 빈 연결이 무의미한 SQL을 실행할 때 세션이 alive로 검증될 수 있도록 다음과 같이 설정하는 것을 추천합니다.
    spring.datasource.druid.test-while-idle=true
    spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
    spring.datasource.druid.validation-query-timeout=1000
    sping.datasource.druid.min-Evictable-Idle-Time-Millis=300000
    sping.datasource.druid.time-Between-Eviction-Runs-Millis=3000
    spring.datasource.druid.keep-alive=true
    spring.datasource.druid.remove-abandoned=true
    spring.datasource.druid.remove-abandoned-timeout=3600
    spring.datasource.druid.log-abandoned=true
    

    일반적으로 상기 설정을 사용하면 더 이상 연결이 끊기는 문제가 발생하지 않습니다.

    2.2 TCP 네트워크

  • keepalive 클래스 유닉스 시스템에서 TCP가 연결된keepalive는 응용층에서 실현할 수도 있고 TCP에서 제공할 수도 있다.이 문제는 논란이 있기 때문에 TCP 연결의 활성 탐지는 TCP 규범의 일부분이 아니다.그러나 편의를 위해 거의 모든 종류의 유닉스 시스템은 TCP에서 해당하는 기능을 제공한다.일반 UNIX 시스템의 tcp keepalive:
    운영 체제
    타이머
    AIX
    # no -a | grep keep
     
    tcp_keepcnt = 8
     
    tcp_keepidle = 14400
     
    tcp_keepintvl = 150
    Linux
    # sysctl -A | grep keep
     
    net.ipv4.tcp_keepalive_intvl = 75
     
    net.ipv4.tcp_keepalive_probes = 9
     
    net.ipv4.tcp_keepalive_time = 7200
    FreeBSD
    #sysctl -A | grep net.inet.tcp
     
    net.inet.tcp.keepidle=…
     
    net.inet.tcp.keepintvl=…
    서로 다른 시스템의 각 매개 변수의 시간 단위는 모두 같지 않다.AIX에서 tcp_keeidle/tcp_keepinit/tcp_keepintvl의 시간 단위는 0.5초입니다.Linux에서는 net.ipv4.tcp_keepalive_intvl와 net.ipv4.tcp_keepalive_시간의 시간 단위는 초이다.또한 상기 매개 변수는 실행 중인 서버에만 연결을 적용합니다.
    note
    Solaris에서 "ndd/dev/tcp\?"명령은 위의 유사한 매개변수 정보를 HP에 표시합니다.
    유닉스에서는 nettune 또는 ndd 명령을 통해 조회할 수 있습니다.모든 유닉스 시스템에서 이러한 기능을 지원하기 때문에 다음 부분에서 우리는 AIX 시스템을 바탕으로 상술한 매개 변수의 의미와 작용 메커니즘을 구체적으로 설명할 것이다.
    제어 매개변수
    매개변수 설명
    tcp_keepcnt
    비활성 연결을 닫기 전에 탐지하는 최대 횟수, 기본 8회
    tcp_keepidle
    연결에 대한 유효성 검사 전에 실행된 최대 유휴 시간, 기본값은 14400(2시간)
    tcp_keepintvl
    두 개의 탐지 시간 간격, 기본값은 150 즉 75초
    이 매개 변수를 설정하여 방화벽이 설정한 최대 유휴 시간보다 제어 시간 간격을 줄이도록 합니다. 방화벽 설정을 이해하지 못하면 이 tcp_keepintvl의 값은 3분 이내로 설정됩니다. 일반적인 네트워크 방화벽은 빈 세션에 대한 제한이 이 시간보다 짧지 않습니다
  • tcpretries는 연결이 이상하게 끊겼지만 프로그램 서버가 관련 종료 정보를 받지 못했을 때 원래 존재하는 세션에서 계속 메시지를 보낼 때 피드백을 받지 않습니다. 일정 시간이 지나면 TCP는 최대 허용 재발송 횟수를 초과할 때까지 이 메시지를 다시 보냅니다.그래서 어떤 시간에는 프로그램에서broken pipe 메시지를 받았을 때 일정 시간 이후(흔히 볼 수 있는 것은 15분)입니다.테스트, 개발자의 눈에는 업무가 시작부터 오류 보고까지 중간에 15분을 기다렸다는 것이다.이것은 리눅스 컴퓨터가 tcp의 메시지 재발송 횟수에 대한 제어와 관련된다:net.ipv4.tcp_retries2, 파일/proc/sys/net/ipv4/tcp_retries2 임시 조정.그 규칙은 재전송 횟수가 9보다 작으면 지수 증가 시간, 9보다 크면 최대 시간 초과 시간을 설정하는 것이다.TCP_RTO_MIN=(HZ/5)=0.2s TCP_RTO_MAX=(120HZ)=120s linear_backoff_thresh = ilog2(1205) = ilog2(0x258) = 9 timeout: linear_를 초과하지 않음backoff_thresh=9 섹션은 TCP_RTO_IN 2의 지수 배율 증가, 초과분은 TCP_RTO_MAX 선형 성장 예:sysctl_tcp_retries2=9, timeout=1023TCP_RTO_MIN=204.6s sysctl_tcp_retries2=11시, timeout=1023TCP_RTO_MIN+2TCP_RTO_MAX=448.6s

  • 이 문제에 대하여 우리는 재전송 횟수를 좀 작게 설정할 수 있다.예를 들어 설정은 3.

    2.3 데이터베이스 감청


    데이터베이스도 오랫동안 아무런 조작도 하지 않은 세션을kill에 떨어뜨리고 피드백을 주지 않습니다.프로그램이 긴 연결을 사용하여 세션을 다시 요청하면 오류가 발생합니다.데이터베이스 측면에서 볼 때 여가 시간을 좀 더 길게 설정할 수 있지만 이렇게 하면 위험이 존재한다. 오랜 세월이 흐른 후에 데이터베이스에 대량의 여가 연결이 존재할 수 있다. 데이터베이스는 일반적으로 최대 연결 수를 제한하기 때문이다.만약 대량의 빈 연결이 존재한다면, 새로운 연결을 만들 수 없을 수도 있습니다.
  • ORACLE oracle에서 유휴 세션에 대한 검사는 $ORACLE_HOME/network/admin/sqlnet.ora에서 설정합니다

  • 네, 매개 변수는 sqlnet입니다.expire_time, 단위는 초입니다.예:
    sqlnet.expire_time=180
    
  • MySQL 설정 wait_timeout 지정된 여가 시간, 단위는 초, 최장 1일을 초과하는 것을 권장하지 않습니다..

  • Author: halberd.lee
    Created: 2019-09-26 Thu 21:20
    Validate

    좋은 웹페이지 즐겨찾기