2012-07-31 23 views
5

Abbiamo una API che utilizza l'ibernazione come strumento ORM e usiamo c3p0 come gestore del pool di connessione. Non abbiamo problemi quando siamo sotto carico. Tuttavia, stiamo esaurendo le eccezioni "impossibile ottenere una connessione" quando l'API è stata inattiva per un giorno circa. Quindi, se nessun corpo usa l'api nel fine settimana, riceviamo errori di connessione lunedì mattina.Collegamenti inattesi dopo il periodo di inattività

Caused by: java.sql.SQLException: An attempt by a client to checkout a Connection has timed out. 

Usiamo mysql come database. Sulla mia ricerca, ho avuto modo di sapere che mySQL rende le connessioni obsolete dopo circa 8 ore. Potrebbe essere possibile che il pool di connessioni stia fornendo una connessione obsoleta al client e quindi le eccezioni di timeout della connessione per il client.

Al momento, non è stato configurato alcun test di connessione in C3Po. Diciamo, se uso IdleTestPeriod per testare la connessione prima che siano dati al client dal pool. Allora cosa succede se tutte le mie connessioni falliscono il test in un punto del tempo? Le connessioni non riuscite verranno rimosse dal pool e le nuove connessioni attive verranno nuovamente generate?

Attualmente, queste sono le impostazioni di c3p0 che stiamo utilizzando. Altre possibili ragioni per questo problema?

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 
     <property name="driverClass" value="${----}"/> 
     <property name="jdbcUrl" value="${----}"/> 
     <property name="user" value="${----}"/> 
     <property name="password" value="${------}"/> 
     <property name="minPoolSize" value="5"/> 
     <property name="acquireIncrement" value="5" /> 
     <property name="maxPoolSize" value="125" /> 
     <property name="maxStatements" value="10" /> 
     <property name="maxIdleTime" value="180" /> 
     <property name="maxIdleTimeExcessConnections" value="30" /> 
     <property name="checkoutTimeout" value="3000" /> 
     <property name="preferredTestQuery" value="SELECT 1" /> 
    </bean> 

Grazie per l'aiuto

risposta

1

Nella sezione di alta disponibilità e il clustering in MySQL Java Connector, dare un'occhiata alle proprietà; in particolare autoReconnect e autoReconnetForPools. Utilizzare le proprietà nell'URL di connessione JDBC. Mi hanno aiutato prima quando uso MySQL, Hibernate e C3P0. Spero che questo aiuti.

9

Così si dispone di un checkoutTimeout di 3 secondi (3000 msecs) impostato. Questa è l'eccezione che vedi. I client possono solo attendere tre secondi per eseguire il checkout di una connessione dal pool; se tre secondi non sono sufficienti, vedono la tua eccezione.

La domanda è: perché i client impiegano così tanto tempo per ottenere una connessione? Normalmente il check-out di una connessione è un'operazione piuttosto veloce. Ma se tutte le connessioni sono state verificate, i client devono attendere l'acquisizione (lenta) della connessione dal database.

Hai la tua piscina configurata per collegare in modo abbastanza aggressivo Collegamenti. Qualsiasi numero di connessioni sopra minPoolSize = 5 verrà distrutto se sono inattivi per più di maxIdleTimeExcessConnections = 30 secondi. Tuttavia, il pool è configurato per burst su larga scala: maxPoolSize = 125. Supponiamo che la tua app rimanga in silenzio per un po ', e poi ottenga una raffica di richieste di connessione dai client. Il pool si esaurirà rapidamente da Connections e inizierà ad acquisire, a raffica di acquireIncrement = 5. Ma se ci sono improvvisamente 25 client e il pool ha solo 5 connessioni, non è improbabile che il 25 ° client possa scadere prima di acquisire una connessione.

C'è molto che puoi fare. Queste modifiche sono separabili, puoi mescolare o abbinare come meglio credi.

1) Eliminare le connessioni "in eccesso" in modo meno aggressivo, in modo che, in generale, la piscina abbia una certa capacità di servire scoppi di richieste. È possibile eliminare completamente maxIdleTimeExcessConnections e lasciare che le connessioni procedano lentamente dopo maxIdleTime = 180 secondi di inattività. (Lato negativo? Un ingombro di risorse più grande più a lungo durante i periodi di inattività)

2) Impostare minPoolSize su un valore superiore, in modo che sia improbabile che il pool vedrà uno scoppio di attività per cui ha troppo poche connessioni (Lato negativo Maggiore impronta di risorse permanenti.)

3) Drop checkoutTimeout dalla configurazione. L'impostazione predefinita di c3p0 è di consentire ai client di attendere indefinitamente per una connessione. (Lato negativo? Forse preferisci che i clienti segnalino rapidamente un fallimento piuttosto che aspettare il possibile successo.)

Non penso che il problema che stai osservando abbia molto a che fare con Test di connessione o timeout MySQL di per sé, ma questo non significa che non dovresti affrontare questi problemi. Mi rimanderò al consiglio di nobeh sul problema della riconnessione di MySQL. (Non sono un grande utente di MySQL.) Dovresti prendere in considerazione l'implementazione del test di connessione. Hai una PreferredQuery, quindi i test dovrebbero essere ragionevolmente veloci. La mia scelta abituale è usare testConnectionOnCheckin e idleConnectionTestPeriod. Vedere http://www.mchange.com/projects/c3p0/#configuring_connection_testing

Buona fortuna!

Problemi correlati