Die Analyse Connection Closed Exception in Spring/JPA/Mysql/Tomcat-app

PROBLEM

Vor kurzem war ich beauftragt, ein Java-web-Anwendung mit dem code, der bereits geschrieben und an Ort und Stelle. Die app empfängt die mäßig hohen traffic und hat peak-Stunden-Verkehr zwischen 11 Uhr bis 3 Uhr jeden Tag.
Die Anwendung verwendet Spring, JPA(Hibernate), MYSQL-DB.
Der Frühling wurde so konfiguriert, tomcat, jdbc-connection-pool, um verbindungen mit der DB.
(Details der Konfiguration am Ende der post)

In den letzten Tagen, während der Anwendung Spitzenlastzeiten, die Anwendung wurde hinunter durch tomcat geht nicht mehr auf Anfragen. Es ist erforderlich, tomcat neu gestartet werden, mehrere Male.

Gehen durch die tomcat catalina.aus Protokollen, die ich bemerkte, eine ganze Menge

Caused by: java.sql.SQLException: Connection has already been closed.
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:117)
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
    at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:80)
    at com.sun.proxy.$Proxy28.prepareStatement(Unknown Source)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:505)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:423)
    at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:139)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1547)
    at org.hibernate.loader.Loader.doQuery(Loader.java:673)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
    at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
    ... 115 more

Diese treten Häufig kurz vor dem Absturz.

Weiter vor, diese Ausnahmen, die ich bemerkt, eine ganze Reihe von Verbindungen aufgegeben, kurz bevor die Verbindung Geschlossen Ausnahmen.

WARNING: Connection has been abandoned PooledConnection[com.mysql.jdbc.Connection@543c2ab5]:java.lang.Exception
    at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:1065)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:782)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:618)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:188)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:128)
    at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:47)
    at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:423)
    at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
    at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:139)

Diese scheinen Häufig, kurz bevor die Verbindung Geschlossen Ausnahmen. Und diese scheinen die ersten Symptome von drohendem Unheil in den logs.

ANALYSE

Gehen durch die logs, die ich sehen, ob es irgendeine Verbindung gibt pool-Konfiguration/mysql-Konfiguration, die möglicherweise das Problem verursacht.
Ging durch ein paar exzellente Artikel, die zeigen, dass tuning den pool für Produktion und Umwelt. Links Eins & Zwei

Gehen durch diesen Artikel, habe ich bemerkt, dass:

  1. Die folgende Zeile in JHanik Artikel (link 1) erwähnt diese

    Einstellung der Wert von abandonWhenPercentageFull 100 würde bedeuten, dass die verbindungen nicht > als aufgegeben, es sei denn, wir haben erreicht, unsere maxActive begrenzen.

    Ich dachte, dies könnte wichtig sein, in meinem Fall, denn ich sehe eine Menge von verbindungen aufgegeben.

  2. Meine max_connections Einstellung nicht übereinstimmt, was empfohlen wird (link 2)

    mysql max_connections sollte gleich max_active+max_idle

, WAS ICH VERSUCHT HABE

So, wie pro die Empfehlungen aus dem Artikel habe ich die folgenden zwei Dinge:

  1. Geändert abandonWhenPercentageFull zu 100
  2. In meinem MYSQL-server, max_connections gesetzt wurde als 500. Erhöhte it-600
    In meinem Verbindungs-pool-Einstellungen, max_active war 200 und max_idle war 50.
    Verändert es max_active=350, max_idle = 250

DIES NICHT HILFT,

Den nächsten Tag, der folgende Beobachtungen gemacht wurden, während der Stoßzeiten:

  1. Tomcat nicht nach unten gehen. Die app blieb während der Stoßzeiten.
    Jedoch ist die Leistung immer schlechter und dann ist die app kaum nutzbar, auch wenn es nicht wirklich nach unten gehen.
  2. DB-Connection-pool, aber erhöht in der Größe, völlig verwertet, und ich konnte sehen, 350 aktive verbindungen zu der DB an einem Punkt.

ENDLICH, MEINE FRAGE:

Er klar sieht aus wie es gibt Probleme mit der Art, wie DB-verbindungen hergestellt sind aus dem app-server.
Also ich habe zwei Richtungen zu nehmen, diese Analyse weiterleiten.

Meine Frage ist welche von diesen sollte ich nehmen?

1. Das Problem ist nicht mit dem Verbindungs-pool-Einstellungen. Der code ist was das Problem verursacht

Möglicherweise gibt es stellen im code, wo DB-verbindungen werden nicht geschlossen. Was ist die Ursache der hohen Anzahl an verbindungen öffnen.

Verwendet der code eine GenericDao die extended in jede Dao-Klasse. Die GenericDao verwendet Spring JpaTemplate zu Holen EntityManager-Instanz, die wiederum für alle DB-Operationen. Mein Verständnis ist mit dem JpaTemplate behandelt die nitty gritty der Schließung DB-verbindungen intern.

Also, wo genau soll ich suchen für eine mögliche undichte Verbindung?

2. Das Problem mit den Anschlüssen pool - /mysql-config-Parameter. Allerdings werden die Optimierungen, die ich haben muss abgestimmt werden, weitere

Wenn ja, welche Parameter sollte ich suchen?
Sollte ich sammeln einige Daten zu verwenden, um zu bestimmen geeigneter Werte für meine connection pool. (Für z.B. für max_active, max_idle, max_connections)


Nachtrag: Vollständige Verbindungs-Pool-Konfiguration

   <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://xx.xx.xx.xx" />
        <property name="username" value="xxxx" />
        <property name="password" value="xxxx" />
        <property name="initialSize" value="10" />
        <property name="maxActive" value="350" />
        <property name="maxIdle" value="250" />
        <property name="minIdle" value="90" />
        <property name="timeBetweenEvictionRunsMillis" value="30000" />
        <property name="removeAbandoned" value="true" />
        <property name="removeAbandonedTimeout" value="60" />
        <property name="abandonWhenPercentageFull" value="100" />
        <property name="testOnBorrow" value="true" />
        <property name="validationQuery" value="SELECT 1" />
        <property name="validationInterval" value="30000" />
        <property name="logAbandoned" value="true" />
        <property name="jmxEnabled" value="true" />
    </bean>

InformationsquelleAutor ncmadhan | 2014-02-11

Schreibe einen Kommentar