2013-08-06 14 views
10

Ich habe eine Menge von Posts in Bezug auf Probleme mit der automatischen Wiederverbindung mit mysql aus Hibernate-Sitzung gelesen. Andere erwähnen einen Anstieg von mysql wait_timeout (nicht mein Favorit), mit autoReconnect = true (nicht empfohlen), testing Verbindung e.t.c. Ich versuche gerade ein paar Optionen, aber ich würde gerne fragen, ob jemand eine solide Lösung hat mit Tomcat Verbindung Pooling (nicht c3po Winterschlaf). Ich schaue mir die meisten kugelsicheren Jndi-Einstellungen an, auch wenn sie nicht die beste Leistung haben.Tomcat 7.0.42 Pooling, Hibernate 4.2, Mysql Rock solide Autoreconnect-Lösung

Vielen Dank,

Grüße

Antwort

21

Ausgezeichnete Frage. Ich habe mich mit dieser Frage herumgeschlagen. Die häufigste Antwort auf stackoverflow ist "Es kommt auf ...." für fast jedes Problem. Ich hasse es zu sagen, aber nein, wo ist das relevanter als die Optimierung Ihres Verbindungspools. Es ist wirklich ein Spiel von Angebot und Nachfrage, bei dem Ihre Verbindungsanforderungen die Nachfrage sind und das Angebot die Anzahl der Verbindungen ist, die MySQL zur Verfügung hat. Es kommt wirklich darauf an, ob es Ihr Hauptanliegen ist zu verhindern, dass veraltete Verbindungen aus dem Pool zurückgegeben werden, oder ob Sie sicherstellen möchten, dass MySQL nicht mit ungenutzten Verbindungen überlastet wird, weil Sie sie nicht schnell genug beseitigen. Die meisten Menschen laugen in der Mitte wo.

Wenn Sie wirklich verstehen, warum jemand eine Verbindungspoolkonfiguration wählen würde, dann glauben Sie mir, dass Sie die Suche nach der "Rocket Solid" -Einstellung abbrechen, weil Sie wissen, dass das wie googlen für einen Geschäftsplan zu Ihrem Geschäft ist; Es hängt vollständig davon ab, wie viele Verbindungsanforderungen Sie erhalten und wie viele dauerhafte Verbindungen Sie bereit stellen möchten. Im Folgenden gebe ich Beispiele, warum Sie bestimmte Einstellungen verwenden würden. Ich referenziere Variablen, die Sie innerhalb des "Resource" -Tags des "Context" -Tags Ihrer Context.xml-Datei ändern müssen. Eine vollständige Beispielkonfiguration ist ganz unten zu sehen.

Low Verkehr

In dieser Situation haben Sie einige Anforderungen an Ihre Anwendung, so gibt es eine gute Chance, alle Verbindungen in Ihrem Connection-Pool gehen abgestanden und die erste Anforderung durch Ihre Anwendung durch eine veraltete Verbindung verursachen ein Fehler. (Je nachdem, welchen MySQL-Treiber Sie verwenden, kann der Fehler erklären, dass das letzte erfolgreich empfangene Paket die Einstellung wait_timeout der Datenbank überschritten hat). Ihre Verbindungspool-Strategie soll also verhindern, dass eine ungültige Verbindung zurückgegeben wird. Die folgenden zwei Optionen haben geringe Nebenwirkung für eine Website mit wenig Verkehr.

  • länger warten, bevor Sie Verbindungen zu töten - Sie würden dies tun, indem Sie den Wert von wait_timeout in Ihrer MySQL-Konfiguration zu ändern. In MYSQL workbench finden Sie diese Einstellung leicht unter Admnin> Konfigurationsdatei> Netzwerk. Für eine Website mit viel Verkehr wird dies nicht oft empfohlen, da dies dazu führen kann, dass der Pool immer mit vielen inaktiven Verbindungen gefüllt wird. Aber denken Sie daran, dies ist das Szenario mit wenig Verkehr.

  • -Test Jede Verbindung - Sie können dies tun, indem testOnBorrow = true und validationQuery= "SELECT 1" Einstellung. Was ist mit Leistung? Sie haben in dieser Situation wenig Verkehr. Das Testen jeder Verbindung, die aus dem Pool zurückgegeben wird, ist kein Problem. Es bedeutet nur, dass jeder MySQL-Transaktion, die Sie für eine einzelne Verbindung ausführen, eine zusätzliche Abfrage hinzugefügt wird. Auf einer wenig befahrenen Website ist das wirklich etwas, über das Sie sich Sorgen machen werden? Das Problem, dass Ihre Verbindungen im Pool liegen, weil sie nicht benutzt werden, ist Ihr Hauptaugenmerk.

Medium Verkehr

  • Überprüfen Sie alle Verbindungen in regelmäßigen Abständen -Wenn Sie nicht möchten, dass jede Verbindung jedes Mal testen, es verwendet wird, oder das Warten Timeout zu verlängern, dann können Sie Testen Sie regelmäßig alle Verbindungen mit einer benutzerdefinierten Standardabfrage oder benutzerdefinierten Abfrage Ihrer Wahl. Zum Beispiel setzen Sie validationQuery = "SELECT 1", testWhileIdle = "true" und timeBetweenEvictionRunsMillis = "3600" oder welches Intervall Sie wollen. Für sehr wenig Verkehr ist dies absolut mehr Arbeit erfordern. Denk darüber nach. Wenn Sie 30 Verbindungen im Pool haben und in 1 Stunde nur 4 Anrufe erhalten, dann hätten Sie leicht alle 4 Verbindungen bei jeder Anfrage mit dem vorherigen testOnBorrow Ansatz mit wenig Leistungseinbußen überprüfen können. Aber wenn Sie stattdessen den Ansatz "Alle stündlich prüfen" ausführen, dann machen Sie 30 Anfragen, um alle Verbindungen zu überprüfen, wenn nur 4 verwendet wurden.

Hauptverkehr

  • Kill-Idle-Verbindungen Früher - Dies ist die Situation, die jeder hat sagen Sie nicht die wait_timeout erweitern sollten und Sie sollte jede Verbindung nicht testen. Es ist kein Modell ideal für jede Situation. Wenn Sie viel Verkehr haben wird jede Verbindung im Pool verwendet werden und Ihr tatsächliches Problem wird die Anzahl der verfügbaren Verbindungen erhöhen, während tatsächlich die Länge Ihrer wait_time verkürzt, so dass Sie nicht enden viele Leerlaufverbindungen auf der DB. Hier ist ein Beispiel für einen Kerl reden, wie er hat bis zu 10.000 Verbindungen im Leerlauf pro Tag für einen belebten Ort so will er die wait_timeout Lowering the wait_timeout for busy site

Probe context.xml Konfiguration

<Context> 

<Resource name="jdbc/TestDB" 
      auth="Container" 
      type="javax.sql.DataSource" 
      factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
      testWhileIdle="true" 
      testOnBorrow="true" 
      testOnReturn="false" 
      validationQuery="SELECT 1" 
      validationInterval="30000" 
      timeBetweenEvictionRunsMillis="30000" 
      maxActive="100" 
      minIdle="10" 
      maxWait="10000" 
      initialSize="10" 
      removeAbandonedTimeout="60" 
      removeAbandoned="true" 
      logAbandoned="true" 
      minEvictableIdleTimeMillis="30000" 
      jmxEnabled="true" 
      jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; 
      org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer" 
      username="root" 
      password="password" 
      driverClassName="com.mysql.jdbc.Driver" 
      url="jdbc:mysql://localhost:3306/mysql"/> 
</Context> 
senken

Probe web.xml Konfiguration

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
    version="2.4"> 
    <description>MySQL Test App</description> 
    <resource-ref> 
     <description>DB Connection</description> 
     <res-ref-name>jdbc/TestDB</res-ref-name> 
     <res-type>javax.sql.DataSource</res-type> 
     <res-auth>Container</res-auth> 
    </resource-ref> 
</web-app> 

Dokumentation auf Tomcat Pool Eigenschaften zwicken Tomcat Pool

+0

Lieber Usman, danke für Ihre Antwort. Ich würde es wirklich schätzen, wenn Sie die obigen Szenarien in mögliche jndi-Ressourcen mit Tomcat-Pooling übersetzen könnten, nicht aber mit c3po. – sygram

+0

Am Ende habe ich nur Beispielkonfigurationen hinzugefügt. Und in jedem Abschnitt des Abschnitts mit wenig Verkehr, mittlerem Verkehr und hohem Verkehr habe ich eine Beschreibung des Tomcat-Pool-spezifischen Feldes hinzugefügt, das Sie in Bezug auf JNDI ändern müssen. Lass es mich wissen, wenn du mehr Klarheit brauchst. –

+0

Um zu meinem obigen Kommentar hinzuzufügen, ist ihr Link ein Link, der zu jedem Feld, das ich ganz unten geändert habe, ins Detail geht. –