복붙노트

[SPRING] 비활성 시간이 지나면 연결이 중단됩니다.

SPRING

비활성 시간이 지나면 연결이 중단됩니다.

내 응용 프로그램에서 Spring은 데이터베이스 액세스를위한 연결 풀을 관리합니다. Hibernate는 질의를 위해 이러한 연결을 사용한다. 얼핏보기에, 나는 풀에 아무런 문제가 없다 : 동시 연결 클라이언트와 하나의 연결 만 가진 풀에서 올바르게 작동한다. 나는 많은 쿼리를 실행할 수 있으므로, 나는 (또는 Spring)이 열린 커넥션을 떠나지 않는다고 생각한다.

내 문제는 일정 시간 동안 사용하지 않으면 (때때로 30 분, 때로는 2 시간 이상) 나타납니다. 그런 다음, Hibernate가 검색을 수행하면 너무 많이 지속됩니다. log4j 수준을 TRACE로 설정하면 다음과 같은 로그가 표시됩니다.

...
18:27:01 DEBUG nsactionSynchronizationManager  - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@99abd7] for key [org.hibernate.impl.SessionFactoryImpl@7d2897] bound to thread [http-8080-Processor24]
18:27:01 DEBUG HibernateTransactionManager     - Found thread-bound Session [org.hibernate.impl.SessionImpl@8878cd] for Hibernate transaction
18:27:01 DEBUG HibernateTransactionManager     - Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@1b2ffee]
18:27:01 DEBUG HibernateTransactionManager     - Creating new transaction with name [com.acjoventut.service.GenericManager.findByExample]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
18:27:01 DEBUG HibernateTransactionManager     - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@8878cd]
18:27:01 TRACE SessionImpl                     - setting flush mode to: AUTO
18:27:01 DEBUG JDBCTransaction                 - begin
18:27:01 DEBUG ConnectionManager               - opening JDBC connection

여기서 약 2 ~ 10 분 동결됩니다. 그러나 계속된다.

18:30:11 DEBUG JDBCTransaction                 - current autocommit status: true
18:30:11 DEBUG JDBCTransaction                 - disabling autocommit
18:30:11 TRACE JDBCContext                     - after transaction begin
18:30:11 DEBUG HibernateTransactionManager     - Exposing Hibernate transaction as JDBC transaction [jdbc:oracle:thin:@212.31.39.50:30998:orcl, UserName=DEVELOP, Oracle JDBC driver]
18:30:11 DEBUG nsactionSynchronizationManager  - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@843a9d] for key [org.apache.commons.dbcp.BasicDataSource@7745fd] to thread [http-8080-Processor24]
18:30:11 DEBUG nsactionSynchronizationManager  - Initializing transaction synchronization
...

그 후 아무런 문제없이 계속 작동합니다. 이휴, 그것은 연결 풀이 잘못된 / 닫힌 연결을 반환하는 것처럼 보이고, 최대 절전 모드가이를 인식하면 풀에 대한 다른 연결을 요청합니다.

나는 어떻게이 문제를 해결할 수 있을지 또는 그것을 구분하기 위해 할 수있는 일을 모르겠다. 이를 달성하는 데 도움이 될 것입니다.

감사.

편집 : 음, 드디어 방화벽 규칙 때문입니다. 데이터베이스 연결이 끊어 졌음이 감지되었지만 풀 (dbcp 또는 c3p0)이 아닙니다. 따라서 성공하지 못한 채 데이터베이스를 조회합니다. 나에게 여전히 이상한 점은 타임 아웃 기간이 매우 다양하다는 것입니다. 어쩌면 규칙이 특별히 이상하거나 방화벽이 올바르게 작동하지 않을 수 있습니다. 어쨌든, 나는 그 기계에 접근 할 수 없으며 나는 단지 설명을 기다릴 수있다. :(

해결법

  1. ==============================

    1.데이터베이스가 별도의 상자에 있고 그 사이에 방화벽이있어 유휴 연결 시간 제한을 설정 한 경우 이와 같은 문제가있었습니다.

    데이터베이스가 별도의 상자에 있고 그 사이에 방화벽이있어 유휴 연결 시간 제한을 설정 한 경우 이와 같은 문제가있었습니다.

    경우에 따라 방화벽은 JDBC 끝이 감지하지 못하도록 연결을 차단하고이를 사용하려고하면 무기한 차단이 발생합니다.

    내 경우에는 풀에서 반환하기 전에 연결을 테스트 쿼리를 보낸 사용자 지정 연결 풀로했습니다. 이 테스트 쿼리가 무한정 차단되지 않도록 Statue.setQueryTimeout을 사용하여 제한 시간을 갖도록 구성했습니다.

  2. ==============================

    2.풀 구현의 구성을 확인하십시오. 대개 아파치 DBCP는 닫힌 후 각 연결에 대해 시간 초과가 있습니다.

    풀 구현의 구성을 확인하십시오. 대개 아파치 DBCP는 닫힌 후 각 연결에 대해 시간 초과가 있습니다.

    코드에서 연결을 유지하면 안됩니다. 하나를 얻고 사용하고 즉시 닫습니다. 수영장은 비용이 많이 들지 않도록합니다.

  3. ==============================

    3.유휴 시간 초과 문제를 해결하는 한 가지 방법은 이중 연결 풀을 활성 화하고 다른 하나가 대기 (아직 연결이 생성되지 않음)하는 것입니다. FIREWALL_IDLE_TIMEOUT보다 훨씬 적은 트리거 시간을 가진 타이머를 가지고 연결 풀을 전환하십시오. 나는 이것을 시도하고 일하고있다.

    유휴 시간 초과 문제를 해결하는 한 가지 방법은 이중 연결 풀을 활성 화하고 다른 하나가 대기 (아직 연결이 생성되지 않음)하는 것입니다. FIREWALL_IDLE_TIMEOUT보다 훨씬 적은 트리거 시간을 가진 타이머를 가지고 연결 풀을 전환하십시오. 나는 이것을 시도하고 일하고있다.

  4. ==============================

    4.데이터 소스에 몇 가지 매개 변수를 추가해야합니다.

    데이터 소스에 몇 가지 매개 변수를 추가해야합니다.

    더 중요한 것은 testOnBorrow 및 validationQuery를 추가합니다.

  5. ==============================

    5.방화벽으로 인해 발생하는 비슷한 증상으로 문제를 해결했습니다.

    방화벽으로 인해 발생하는 비슷한 증상으로 문제를 해결했습니다.

    연결이 유휴 상태가되는 것을 방지하는 testWhileIdle 연결 풀 등록 정보와 연결을 종료하는 방화벽을 변경하여이 문제를 해결할 수있었습니다. Apache commons dbcp BasicDataSource를 참조하십시오. 다음은 문제를 수정 한 구성 파일 persistentce-context.xml의 내용입니다.

    <property name="testWhileIdle">
      <value>true</value>
    </property>
    <property name="minEvictableIdleTimeMillis">
      <value>600000</value>
    </property>
    <property name="timeBetweenEvictionRunsMillis">
      <value>600000</value>
    </property>
    

    대부분 우리는 testWhileIdle (기본값은 false)을 추가하기 만하면되지만 다른 두 개의 속성은 좋은 측정을 위해 추가되었습니다.

    우리의 경우 여기에 우리가보고 있던 로그가 있습니다. 이 디버그 로그를 보면 연결을 사용하기 전에 연결을 여는 데 16 분이 걸릴 것이므로 모든 연결이 끊어졌습니다. 추적하기가 어려운 오류는 없었습니다.

    09-06-13 @ 16:36:34 [DEBUG] HibernateTransactionManager - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@db17ab]
    09-06-13 @ 16:36:34 [DEBUG] ConnectionManager - opening JDBC connection
    09-06-13 @ 16:52:00 [DEBUG] DataSourceUtils - Setting JDBC Connection
    09-06-13 @ 16:52:00 [DEBUG] JDBCTransaction - begin
    09-06-13 @ 16:52:00 [DEBUG] JDBCTransaction - current autocommit status: true
    
  6. from https://stackoverflow.com/questions/1888923/connection-hangs-after-time-of-inactivity by cc-by-sa and MIT license