2 Stimmen

Hibernate/Spring: Viele (Tausende) offene Verbindungen zur Datenbank

Ich habe auf meinem Server eine Spring/Hibernate/MySQL-Anwendung bereitgestellt. Seit einigen Tagen habe ich das Problem, dass meine Anwendung anscheinend viele Verbindungen zur Datenbank öffnet. Ich habe diesen Hinweis aus einer Netstat-Ausgabe, die wie folgt aussieht (IP-Adressen verdeckt):

tcp6       0      0 ************:53547       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53595       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53645       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:34986       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53669       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53710       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53757       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53716       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53627       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53752       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53505       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53549       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:35185       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53604       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:35331       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53488       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:34938       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:34987       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53695       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:35380       ************:3306        TIME_WAIT   0          0           -
tcp6       0      0 ************:53651       ************:3306        TIME_WAIT   0          0           -

Wenn ich jedoch auf die MySQL Workbench Server Health-Registerkarte für meine MySQL-Datenbank schaue, sieht alles so aus, als ob alles in Ordnung wäre (siehe beigefügter Screenshot).

Außerdem hat meine Anwendung eine normale Leistung.

Wir entwickeln derzeit aktiv an der Anwendung, können aber keine Codeänderungen erkennen, die sich auf dieses Verhalten auswirken. Es muss offensichtlich eine Änderung gegeben haben, aber es könnte auch ein Konfigurationsproblem oder Ähnliches sein.

Könnte es ein Hibernate-Verbindungspool sein? Das Seltsame ist, dass alle Verbindungen warten.

Ich bin dankbar für alle Ideen und Hinweise!

Bearbeitung - Hibernate-Konfiguration (mit Spring)

        com.mysql.jdbc.Driver

        jdbc:mysql://************:3306/******** 

        ********

        ********

            WEB-INF/hibernate.hbm.xml

            org.hibernate.cfg.AnnotationConfiguration

                org.hibernate.dialect.MySQL5InnoDBDialect
                0
                false
                cglib
                update

LÖSUNG: Ich habe mich jetzt entschieden, die Tomcat JNDI-Datenquelle zu verwenden, und es funktioniert endlich. Es werden nur 11(!!) Verbindungen zur Datenbank genutzt ;) Danke @Vineet Reynolds

4voto

Vineet Reynolds Punkte 74302

Die Hibernate-Dokumentation beschreibt, wie Verbindungspools in Hibernate erstellt werden:

Hibernate erhält und verwaltet Verbindungen mithilfe von java.sql.DriverManager, wenn Sie die folgenden Eigenschaften setzen:

Tabelle 3.1. Hibernate JDBC-Eigenschaften

Eigenschaft         Zweck
hibernate.connection.driver_class   JDBC-Treiberklasse
hibernate.connection.url            JDBC-URL
hibernate.connection.username       Datenbankbenutzer
hibernate.connection.password       Datenbankbenutzerpasswort
hibernate.connection.pool_size      maximale Anzahl der verwalteten Verbindungen

und noch wichtiger:

Das eigene Verbindungspooling-Algorithmus von Hibernate ist jedoch sehr rudimentär. Es soll Ihnen helfen, anzufangen und ist nicht für den Einsatz in einem Produktionssystem oder sogar für Leistungstests gedacht.

Es wäre sinnvoll zu überprüfen, ob die in der Dokumentation beschriebenen Werte verwendet werden, was dazu führen würde, dass Hibernate den Pool verwaltet, ohne das Pool-Management an eine für die Produktion geeignete Verbindungspool-Implementierung zu delegieren.

Was die Ausgabe von netstat betrifft, sind die Anzahl der Verbindungen und der Grund für deren Öffnung die wichtigsten Kriterien zur Entscheidung, ob Sie ein Problem haben. Normalerweise öffnen für die Produktion geeignete Pool-Implementierungen Verbindungen nur bei Bedarf und haben auch die Möglichkeit, die Poolgrößen zu reduzieren. Darüber hinaus können Verbindungen von einem solchen Pool-Manager abgebrochen werden, wenn sie nicht verwendet werden. Es scheint, dass der Server aufgrund der Anzahl von Verbindungen im Zustand TIME_WAIT auf Datenverkehr vom Client wartet; dies könnte der Fall sein, dass physische Verbindungen nicht geschlossen werden, nachdem sie nicht mehr benötigt werden.

All diese Beobachtungen haben jedoch nur einen resultierenden Vorschlag - verwenden Sie eine Verbindungspool-Implementierung, die besser ist als die Standardimplementierung und deren Leistungseigenschaften ebenfalls gut verstanden werden. Sie würden Empfehlungen erhalten, c3p0 oder BoneCP zu verwenden, von vielen Leuten hier.

Aktualisierung

Basierend auf der geposteten Spring Hibernate-Konfiguration scheint ein DataSource verwendet zu werden, um Verbindungen für Hibernate zu erhalten. Die Konfiguration des zugrunde liegenden Verbindungspools hinter dem DataSource wäre daher in Gebrauch.

Aktualisierung Nr. 2

Die aktualisierte Spring-Anwendungscontext-Datei verwendet den DriverManagerDataSource aus dem Spring-Framework. Wie es in der Dokumentation wörtlich heißt:

HINWEIS: Diese Klasse ist kein tatsächlicher Verbindungspool; sie verwaltet tatsächlich keine Verbindungen. Sie dient lediglich als einfacher Ersatz für einen umfassenden Verbindungspool, der dieselbe Standard-Schnittstelle implementiert, aber bei jedem Aufruf neue Verbindungen erstellt.

Wichtig ist zu beachten, dass DriverManagerDataSource auf die ihm bereitgestellten Eigenschaften angewiesen ist, um die Verbindung zu erstellen. Und wie in der Dokumentation angegeben, würde es den DriverManager statt einer JNDI-gebundenen DataSource verwenden, um die Verbindungen zu erstellen. Ein wichtiger Punkt hier ist, dass der DriverManager normalerweise physische Verbindungen zur Datenbank zurückgibt, im Gegensatz zu DataSources, die logische Verbindungsummantelungen zurückgeben. Es scheint (aus der netstat-Ausgabe), dass diese physischen Verbindungen nicht geschlossen werden. Vielleicht schließt Hibernate die Verbindungen nicht; aber das ist unwahrscheinlich; Sie sollten besser eine bessere Verbindungspool-Implementierung verwenden, die so konfiguriert werden kann, dass eine tatsächliche Gruppe von Verbindungsobjekten vorhanden ist, deren Anzahl niemals die Poolgröße überschreitet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X