2013-08-06 10 views
10

ho letto un sacco di post riguardanti i problemi con la riconnessione automatica a mysql dalla sessione di ibernazione. Altri menzionano un aumento di mysql wait_timeout (non il mio preferito), utilizzando autoReconnect = true (non consigliato), test di connessione e.t.c. Attualmente sto provando alcune opzioni, ma vorrei chiedere se qualcuno ha una soluzione solida utilizzando il pool di connessioni di Tomcat (non il c3po di Hibernate). Sto osservando le impostazioni jndi più a prova di proiettile anche se non sono le migliori prestazioni messe a punto.tomcat 7.0.42 pooling, hibernate 4.2, mysql rock soluto soluzione autoreconnect

La ringrazio molto,

saluti

risposta

21

Ottima domanda. Io uso per lottare con questa domanda. La risposta più comune su StackOverflow è "Dipende ..." praticamente per ogni problema. Odio dirlo ma non è più pertinente che modificare il tuo pool di connessioni. È davvero un gioco di domanda e offerta, dove le richieste di connessione sono la domanda e l'offerta è il numero di connessioni che MySQL ha a disposizione. Dipende veramente dal fatto che la tua preoccupazione principale sia quella di impedire che le connessioni stantie vengano restituite dal pool, o se la tua preoccupazione è garantire che MySQL non sia sovraccaricato di connessioni inattive perché non le stai uccidendo abbastanza velocemente. La maggior parte delle persone liscivia in mezzo dove.

Se si capisce davvero perché qualcuno dovrebbe scegliere una qualsiasi configurazione di un pool di connessioni, credetemi, smetterete di cercare l'impostazione "Rocket Solid" perché saprete che è come cercare un business plan per il vostro negozio; È interamente basato sul numero di richieste di connessione ottenute e sul numero di connessioni persistenti che si desidera rendere disponibili. Di seguito fornisco esempi del motivo per cui usereste determinate impostazioni. Faccio riferimento alle variabili che dovrai modificare all'interno del tag "Risorsa" del tag "Contesto" del tuo file Context.xml. Un esempio di configurazione completa può essere visto in fondo.

traffico low

In questa situazione si hanno alcune richieste per l'applicazione in modo non v'è una buona probabilità tutti i collegamenti vostro pool di connessioni andrà stantio e la prima richiesta per l'applicazione da un collegamento stantio causerà un errore. (A seconda del driver MySQL che si sta utilizzando, l'errore potrebbe spiegare che l'ultimo pacchetto di successo ricevuto ha superato l'impostazione wait_timeout del database). Quindi la strategia del pool di connessioni è impedire che venga restituita una connessione non funzionante. Le seguenti due opzioni hanno un piccolo effetto collaterale per un sito a basso traffico.

  • aspettare più a lungo prima di uccidere Connessioni - Si potrebbe fare questo modificando il valore di wait_timeout nella configurazione di MySQL. Nel workbench di MYSQL è possibile trovare facilmente questa impostazione in Admnin> File di configurazione> Networking. Per un sito con un sacco di traffico questo non è spesso raccomandato perché può portare al pool sempre pieno di molte connessioni inattive. Ma ricorda che questo è lo scenario di traffico limitato .

  • test ogni connessione - È possibile farlo impostando testOnBorrow = true e validationQuery= "SELECT 1". Che dire delle prestazioni? Hai poco traffico in questa situazione. Testare ogni connessione restituita dal pool non è un problema. Tutto ciò significa che verrà aggiunta una query aggiuntiva a ogni transazione MySQL che si sta eseguendo su una singola connessione. Su un sito a basso traffico è davvero qualcosa di cui ti preoccuperai? Il problema delle connessioni che si interrompono nel pool perché non vengono utilizzate è il tuo obiettivo principale.

medio di traffico

  • controllare tutte le connessioni periodicamente -Se non vogliono testare ogni connessione ogni volta che viene usato, o estendere il timeout di attesa, allora si può testare periodicamente tutte le connessioni con una query personalizzata predefinita o di propria scelta. Ad esempio, imposta validationQuery = "SELECT 1", testWhileIdle = "true" e timeBetweenEvictionRunsMillis = "3600" o qualsiasi altro intervallo tu voglia. Per il traffico molto basso questo è che richiede assolutamente più lavoro. Pensaci. Se si dispone di 30 connessioni nella piscina e in 1 ora solo 4 vengono richiamati, è possibile verificare facilmente tutte e 4 le connessioni su ogni richiesta utilizzando l'approccio testOnBorrow precedente con scarso rendimento. Ma se invece fai l'approccio "Controlla tutte le ore", allora fai 30 richieste per verificare tutte le connessioni quando sono stati usati solo gli 4.

ad alto traffico

  • Uccidi Connessioni Idle Prima - Questa è la situazione che ha tutti dicendo che non si deve estendere l'wait_timeout e si non si dovrebbe verificare ogni connessione. Non è un modello ideale per ogni situazione. Quando si dispone di traffico significativo verrà utilizzata ogni connessione nel pool e il tuo problema reale aumenterà il numero di connessioni disponibili mentre accorciando effettivamente la lunghezza del tuo wait_time in modo da non finire molte connessioni inattive sul DB. Ecco un esempio di un tipo parlando di come ha fino a 10.000 connessioni inattive al giorno per un sito occupato in modo che vuole ridurre il wait_timeout Lowering the wait_timeout for busy site

Esempio di configurazione 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> 

Esempio di configurazione 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> 

Documentazione su Tomcat Pool proprietà a tweak Tomcat Pool

+0

Caro Usman, grazie per la risposta. Sarei davvero grato se potessi tradurre gli scenari di cui sopra in possibili risorse jndi con il pool di tomcat, non con c3po. – sygram

+0

Alla fine ho appena aggiunto configurazioni di esempio. E in ciascuna sezione a basso traffico, traffico medio e traffico elevato, i paragrafi I hanno aggiunto una descrizione del campo specifico del pool Tomcat che dovrai modificare in relazione a JNDI. Fammi sapere se hai bisogno di ulteriori chiarimenti. –

+0

Per aggiungere al mio commento sopra, il loro è un link che entra nei dettagli di ogni campo che ho modificato in fondo. –

Problemi correlati