Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Tomcat 7.0.42 Pooling, Hibernate 4.2, Mysql Rock Solid AutoReconnect-Lösung

Ausgezeichnete Frage. Ich habe mit dieser Frage zu kämpfen. Die häufigste Antwort auf Stackoverflow ist "Es hängt davon ab ..." für praktisch jedes Problem. Ich hasse es, es zu sagen, aber nirgendwo ist das relevanter, als Ihren Verbindungspool zu optimieren. Es ist wirklich ein Spiel von Angebot und Nachfrage, bei dem Ihre Verbindungsanfragen die Nachfrage sind und das Angebot die Anzahl der Verbindungen, die MySQL zur Verfügung hat. Es kommt wirklich darauf an, ob Ihr Hauptanliegen darin besteht, zu verhindern, dass veraltete Verbindungen aus dem Pool zurückgegeben werden, oder ob Ihr Anliegen darin besteht, sicherzustellen, dass MySQL nicht mit inaktiven Verbindungen überlastet wird, weil Sie sie nicht schnell genug beenden. Die meisten Menschen liegen irgendwo in der Mitte.

Wenn Sie wirklich verstehen, warum jemand eine Verbindungspool-Konfiguration wählen würde, dann glauben Sie mir, Sie werden aufhören, nach der Einstellung „Rocket Solid“ zu suchen, weil Sie wissen, dass dies so ist, als würden Sie nach einem Geschäftsplan für Ihr Geschäft googeln. Es hängt ganz davon ab, wie viele Verbindungsanfragen Sie erhalten und wie viele dauerhafte Verbindungen Sie bereit sind, zur Verfügung zu stellen. Im Folgenden gebe ich Beispiele dafür, warum Sie bestimmte Einstellungen verwenden würden. Ich verweise auf 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.

Geringer Traffic

In dieser Situation haben Sie nur wenige Anforderungen an Ihre Anwendung, daher besteht eine gute Chance, dass ALLE Verbindungen in Ihrem Verbindungspool veraltet sind und die erste Anforderung Ihrer Anwendung durch eine veraltete Verbindung einen Fehler verursacht. (Abhängig vom MySQL-Treiber, den Sie verwenden, kann der Fehler erklären, dass das letzte erfolgreich empfangene Paket die Wait_timeout-Einstellung der Datenbank überschritten hat). Ihre Strategie für den Verbindungspool besteht also darin, zu verhindern, dass eine tote Verbindung zurückgegeben wird. Die folgenden beiden Optionen haben nur geringe Nebenwirkungen für eine Website mit geringem Datenverkehr.

  • Warten Sie länger, bevor Sie Verbindungen beenden - Sie würden dies tun, indem Sie den Wert von wait_timeout ändern in Ihrer MySQL-Konfiguration. In MYSQL Workbench finden Sie diese Einstellung ganz einfach unter Administration> Konfigurationsdatei> Netzwerk. Für eine Site mit viel Datenverkehr wird dies oft nicht empfohlen, da es dazu führen kann, dass der Pool immer mit vielen inaktiven Verbindungen gefüllt wird. Denken Sie jedoch daran, dass dies das Szenario mit geringem Datenverkehr ist.

  • Jede Verbindung testen - Sie können dies tun, indem Sie testOnBorrow = true setzen und validationQuery= "SELECT 1" . Was ist mit der Leistung? In dieser Situation haben Sie wenig Verkehr. Das Testen jeder vom Pool zurückgegebenen Verbindung ist kein Problem. Dies bedeutet lediglich, dass jeder MySQL-Transaktion, die Sie über eine einzelne Verbindung ausführen, eine zusätzliche Abfrage hinzugefügt wird. Auf einer wenig frequentierten Website ist das wirklich etwas, worüber Sie sich Sorgen machen werden? Das Problem, dass Ihre Verbindungen im Pool tot sind, weil sie nicht verwendet werden, ist Ihr Hauptaugenmerk.

Mittlerer Traffic

  • Überprüfen Sie regelmäßig alle Verbindungen -Wenn Sie nicht jede Verbindung bei jeder Verwendung testen oder die Wartezeit verlängern möchten, können Sie regelmäßig alle Verbindungen mit einer Standard- oder benutzerdefinierten Abfrage Ihrer Wahl testen. Setzen Sie zum Beispiel validationQuery = "SELECT 1" , testWhileIdle = "true" , und timeBetweenEvictionRunsMillis = "3600" oder welches Intervall Sie wollen. Bei sehr geringem Datenverkehr wird dies absolut mehr Arbeit erfordern. Denk darüber nach. Wenn Sie 30 Verbindungen im Pool haben und in 1 Stunde nur 4 angerufen werden, dann hätten Sie mit dem vorherigen testOnBorrow problemlos alle 4 Verbindungen bei jeder Anfrage überprüfen können Ansatz mit wenig Leistungseinbußen. Aber wenn Sie stattdessen den Ansatz "Alle jede Stunde überprüfen" verwenden, stellen Sie 30 Anfragen, um alle Verbindungen zu überprüfen, wenn nur 4 verwendet wurden.

Hoher Verkehr

  • Leere Verbindungen früher beenden - Dies ist die Situation, in der alle sagen, dass Sie das wait_timeout nicht verlängern und nicht jede Verbindung testen sollten. Es ist kein ideales Modell für jede Situation. Wenn Sie erheblichen Datenverkehr haben, wird jede Verbindung im Pool verwendet, und Ihr eigentliches Problem besteht darin, die Anzahl der verfügbaren Verbindungen zu erhöhen, während die Länge Ihrer wait_time tatsächlich verkürzt wird Sie beenden also nicht viele ungenutzte Verbindungen in der DB. Hier ist ein Beispiel von einem Kerl, der darüber spricht, wie er bis zu 10.000 ungenutzte Verbindungen pro Tag für eine stark ausgelastete Website hat, also möchte er das wait_timeout Verringern des wait_timeout für stark frequentierte Sites

Beispielkonfiguration für Context.xml

<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>

Beispielkonfiguration für web.xml

<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 zu Tomcat-Pool-Eigenschaften zum Anpassen von Tomcat-Pool