2017-11-20 2 views
1

저는 스프링 부트 애플리케이션에서 연결 풀링을 위해 c3p0을 몇 달 동안 사용해 왔습니다. 특히 아침에 연결 문제가 발생하기 시작한 약 2 주 전까지는 문제가 없었습니다. 매일 아침 내 응용 프로그램에 로그인하려고하면 Could not open connection 오류가 발생합니다. 그런 다음 문제를 제거하기 위해 응용 프로그램을 다시 시작합니다. 문제의 근본 원인을 파악할 수 없습니다. 나는에-케이스 (미 반환 연결을 추려 내 응용 프로그램에 C3P0 디버그 구성을 추가 한c3p0을 사용함에도 불구하고`Could not open connection` 문제가 발생했습니다.

public class HibernateUtil { 

private static final SessionFactory sessionFactory; 
static { 
    try { 
     Configuration configuration = new Configuration().configure(); 
     StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder() 
       .applySettings(configuration.getProperties()); 
     sessionFactory = configuration.buildSessionFactory(builder.build()); 

    } catch (Exception ex) { 
     throw new ExceptionInInitializerError(ex); 
    } 
} 

public Session openSession() { 
    return sessionFactory.openSession(); 
} 
} 

:

hibernate-configuration> 
<session-factory> 
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb?autoReconnect=true</property> 
    <property name="hibernate.connection.username">root</property> 
    <property name="hibernate.connection.password">abc123</property> 
    <property name="hibernate.dialect">config.CustomDialect</property> 

    <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> 
    <property name="hibernate.c3p0.initialPoolSize">5</property> 
    <property name="hibernate.c3p0.minPoolSize">5</property> 
    <property name="hibernate.c3p0.maxPoolSize">100</property> 
    <property name="hibernate.c3p0.checkoutTimeout">3000</property> 
    <property name="hibernate.c3p0.maxStatementsPerConnection">30</property> 
    <property name="hibernate.c3p0.unreturnedConnectionTimeout">3000</property> 
    <property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces">true</property> 

    <property name="show_sql">true</property> 
    <property name="format_sql">true</property> 
    <property name="hbm2ddl.auto">update</property> 

... 
POJO mappings 
</session-factory> 
</hibernate-configuration> 

가 여기 내 HibernateUtil과 클래스의 : 여기

내 hibernate.cfg.xml로의 메모리 누수) 및 스택 추적을 생성하지만 아무것도 로그에 표시되지 않습니다.

다음은이 아침부터 로그의 일부입니다 :

https://pastebin.com/MGb4Miau

여기 사람이 문제가 자리하고있는 곳 나를내는 데 도움이 수 있습니까?

편집 : CustomDialect 클래스 : 당신이 데이터베이스 연결의 부족 때문에

public class CustomDialect extends MySQL5InnoDBDialect { 
public String getTableTypeString() { 
    return " ENGINE=InnoDB DEFAULT CHARSET=utf8"; 
    } 
} 

답변

0

마침내 문제의 해결책을 알아 냈습니다.

<property name="hibernate.c3p0.maxIdleTime">10800</property> 
<property name="hibernate.c3p0.maxIdleTimeExcessConnections">600</property> 

을 그리고 그것은 작동 : 내 hibernate.cfg.xml에 다음과 같이 변경했다! maxIdleTime 속성은 지정된 시간 (초) 동안 풀에서 유휴 상태 인 연결을 제거하여 때때로 내 연결이 새로 고쳐 지도록하고 maxIdleTimeExcessConnections은 풀에서 풀을 연결하여 minPoolSize을 초과하는 연결을 제거하도록합니다 지정된 시간 (초 단위) 이상 유휴 상태였습니다. 이렇게하면 수영장에 너무 많은 연결이 없으며 모두 신선합니다.

0

이 문제가 나타납니다.

  1. 너무 느린 연결을 보유하는 쿼리.
  2. 최대 풀 크기 100에 맞지 않는 연결 요구가 많습니다. 실행 당일 후에 문제가 나타나기 때문에 예상되는 원인입니다.
  3. 또는 트랜잭션이 성공했거나 실패한 후 연결을 닫지 않았으므로 소스 누출이 있습니다.

C3P0에서 디버깅 할 때 요청되는 연결 수를 확인하십시오. 당신은 연결 누수를 디버깅해야하고 당신이있을 때 더 이상 누출 모두 unreturnedConnectionTimeoutdebugUnreturnedConnectionStackTraces 설정을 제거하지 않도록 또한

이상적으로

, 당신은, 생산 unreturnedConnectionTimeout를 사용하지 않아야합니다. 편집


는 이러한 설정을 시도해보십시오

<property key="hibernate.connection.characterEncoding">UTF-8</property> <property key="hibernate.connection.useUnicode">true</property> 

때때로 최대 절전 모드에서 인코딩의 MySQL DB의 인코딩 다르기 때문에

.

+0

Ebraheem, 연결 유출을 알아 내기 위해'unreturnedConnectionTimeout'과'debugUnreturnedConnectionStackTraces' 설정을했습니다. 지금까지 아무 것도 로그에 표시되지 않습니다. 또한 SonarQube를 사용하여 소스 코드를 스캔 했으므로 리소스 유출도 감지되지 않습니다. 내가 놀랍게 생각하는 것은 c3p0과'unreturnedConnectionTimeout'과'debugUnreturnedConnectionStackTraces' 설정을 사용하고 있음에도 불구하고 46,956,212 ms 또는 ~ 13hr까지의 연결 비활성이 발생한다는 것입니다. –

+0

'checkoutTimeout'을 줄이려고 했습니까? –

+0

또한 서버로부터 성공적으로받은 마지막 패킷은 약 13 시간 전에 있었는데, 나는 앱이 언제 시작될지를 묻고 싶다 –

관련 문제