Opzioni di pool di connessioni con JDBC: DBCP vs C3P0


312

Qual è la migliore libreria di pool di connessioni disponibile per Java / JDBC?

Sto considerando i 2 candidati principali (gratuiti / open-source):

Ho letto molto su di loro nei blog e in altri forum, ma non sono riuscito a prendere una decisione.

Esistono alternative pertinenti a questi due?

Risposte:


181

DBCP non è aggiornato e non è di livello produttivo. Qualche tempo fa abbiamo condotto un'analisi interna dei due, creando un dispositivo di prova che ha generato carico e concorrenza rispetto ai due per valutare la loro idoneità in condizioni di vita reali.

DBCP ha generato costantemente eccezioni nella nostra applicazione di test e ha lottato per raggiungere livelli di prestazioni che C3P0 era più che in grado di gestire senza eccezioni.

C3P0 ha anche gestito in modo robusto le disconnessioni dei DB e le riconnessioni trasparenti al riavvio, mentre DBCP non ha mai recuperato le connessioni se il collegamento è stato rimosso da sotto di esso. Peggio ancora, DBCP stava restituendo gli oggetti Connection all'applicazione per la quale il trasporto sottostante si era rotto.

Da allora abbiamo usato C3P0 in 4 importanti app Web di consumo per carichi pesanti e non abbiamo mai guardato indietro.

AGGIORNAMENTO: Si scopre che dopo molti anni passati a sedere su uno scaffale, la gente di Apache Commons ha rimosso DBCP dalla dormienza e ora è, ancora una volta, un progetto sviluppato attivamente. Quindi il mio post originale potrebbe non essere aggiornato.

Detto questo, non ho ancora sperimentato le prestazioni di questa nuova libreria aggiornata, e non ne ho mai sentito parlare di fatto in un recente framework di app.


2
Grazie! Che ne pensi dell'alternativa Proxool suggerita? La versione corrente di Hibernate viene fornita con c3p0 e Proxool.
Dema,

Non abbiamo provato Proxool ma ora lo verificherò :)
j pimmel,

5
c3p0 presenta alcuni inconvenienti. a volte non riesce a gestire i picchi di connessione.
Janning,

3
le cose sono cambiate molto da 4 anni quando hai pubblicato questa risposta per la prima volta, potresti aggiungere un aggiornamento condividendo lo scenario attuale, se possibile?
Rajat Gupta,

13
Consiglio vivamente HikariCP , ma poi ho contribuito a scriverlo.
Brettw

177

Ti invito a provare BoneCP : è gratuito, open source e più veloce delle alternative disponibili (vedi sezione benchmark).

Disclaimer: sono l'autore, quindi potresti dire che sono di parte :-)

AGGIORNAMENTO: A partire da marzo 2010, ancora circa il 35% più veloce del nuovo pool Apache DBCP ("tomcat jdbc") riscritto. Vedi link benchmark dinamico nella sezione benchmark.

Aggiornamento n. 2: (dicembre '13) Dopo 4 anni al vertice, ora c'è un concorrente molto più veloce: https://github.com/brettwooldridge/HikariCP

Aggiornamento n. 3: (settembre '14) Considerare che BoneCP è obsoleto a questo punto, si consiglia di passare a HikariCP .

Aggiornamento n. 4: (aprile '15) - Non possiedo più il dominio jolbox.com


1
Mi piacerebbe davvero ottenere una risoluzione dei problemi utilizzando BoneCP come origine dati Tomcat. Il problema principale che ho avuto con questo era che richiedeva le classi BoneCP nella directory lib di tomcat, così come le classi log4j e google. In questo modo i pool di connessione funzionavano - (non aveva funzionato in WAR) - tuttavia era in conflitto con l'impostazione log4j di Tomcat e impediva qualsiasi output del registro dall'applicazione, che era un rompicapo ...
j pimmel

1
Sembra un problema log4j più di ogni altra cosa. Mandami una riga su forum.jolbox.com e ti aiuterò a rintracciarlo al più presto.
wwadge,

3
1up, BoneCP è geniale. Passato da C3P0. Mi ha anche permesso di rimuovere la mia dipendenza da log4jdbc-remix, perché consente la registrazione delle istruzioni fuori dalla scatola!
subisce il

68
+1 per l'aggiornamento su qualcosa che non hai scritto per essere più veloce!
Coray:

1
@AndrewScottEvans Probabilmente è meglio tornare alla v0.7.1
wwadge,

16

Avevo problemi con DBCP quando scadevano le connessioni, quindi ho provato c3p0. Stavo per rilasciare questo alla produzione, ma poi ho iniziato i test delle prestazioni. Ho scoperto che c3p0 ha funzionato terribilmente. Non sono riuscito a configurarlo per funzionare bene. L'ho trovato due volte più lento di DBCP.

Ho quindi provato il pool di connessioni Tomcat .

Questo era due volte più veloce di c3p0 e risolto altri problemi che stavo riscontrando con DBCP. Ho trascorso molto tempo a studiare e testare i 3 pool. Il mio consiglio se si sta eseguendo la distribuzione su Tomcat è di utilizzare il nuovo pool Tomcat JDBC.


14

Per il problema di riconnessione automatica con DBCP, hai mai provato a utilizzare i seguenti 2 parametri di configurazione?

validationQuery="Some Query"

testOnBorrow=true

Per quanto riguarda la documentazione , testOnBorrowha un valore predefinito true, quindi se validationQueryè definito DBCP testerà ogni connessione prima che venga passata all'applicazione.
dma_k,


12

Usano DBCP da un paio d'anni ormai in produzione. È stabile, sopravvive al riavvio del server DB. Basta configurarlo correttamente. Richiede solo una manciata di parametri da specificare, quindi non essere pigro. Ecco uno snippet dal nostro codice di produzione del sistema che elenca i parametri che abbiamo impostato esplicitamente per farlo funzionare:

DriverAdapterCPDS driverAdapterCPDS = new DriverAdapterCPDS();
driverAdapterCPDS.setUrl(dataSourceProperties.getProperty("url"));
driverAdapterCPDS.setUser(dataSourceProperties.getProperty("username"));
driverAdapterCPDS.setPassword(dataSourceProperties.getProperty("password"));
driverAdapterCPDS.setDriver(dataSourceProperties.getProperty("driverClass"));

driverAdapterCPDS.setMaxActive(Integer.valueOf(dataSourceProperties.getProperty("maxActive")));
driverAdapterCPDS.setMaxIdle(Integer.valueOf(dataSourceProperties.getProperty("maxIdle")));
driverAdapterCPDS.setPoolPreparedStatements(Boolean.valueOf(dataSourceProperties.getProperty("poolPreparedStatements")));

SharedPoolDataSource poolDataSource = new SharedPoolDataSource();
poolDataSource.setConnectionPoolDataSource(driverAdapterCPDS);
poolDataSource.setMaxWait(Integer.valueOf(dataSourceProperties.getProperty("maxWait")));
poolDataSource.setDefaultTransactionIsolation(Integer.valueOf(dataSourceProperties.getProperty("defaultTransactionIsolation")));
poolDataSource.setDefaultReadOnly(Boolean.valueOf(dataSourceProperties.getProperty("defaultReadOnly")));
poolDataSource.setTestOnBorrow(Boolean.valueOf(dataSourceProperties.getProperty("testOnBorrow")));
poolDataSource.setValidationQuery("SELECT 0");

8

Ecco alcuni articoli che mostrano che DBCP ha prestazioni significativamente più elevate rispetto a C3P0 o Proxool. Anche nella mia esperienza c3p0 ha alcune caratteristiche interessanti, come il pooling di istruzioni preparato ed è più configurabile di DBCP, ma DBCP è chiaramente più veloce in qualsiasi ambiente in cui l'ho utilizzato.

Differenza tra dbcp e c3p0? Assolutamente niente! (Un blog per sviluppatori Sakai) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

Vedi anche i simili all'articolo JavaTech "Showdown del pool di connessioni" nei commenti sul post del blog.


4
più veloce in ambienti a thread singolo, forse difettoso e instabile e semplicemente rotto altrove.

7

Un'altra alternativa, Proxool, è menzionata in questo articolo .

Potresti essere in grado di scoprire perché Hibernate raggruppa c3p0 per l'implementazione predefinita del pool di connessioni?


7

Sfortunatamente sono tutti obsoleti. DBCP è stato aggiornato un po 'di recente, gli altri due hanno 2-3 anni, con molti bug in sospeso.


Questo è vero - l'ultima versione di C3PO (una pre-release 0.9) è del maggio 2007. L'ultima versione di Proxool (una pre-release 0.9) è di agosto 2008. L'ultima versione di DBCP è anch'essa dell'aprile 2007, ma almeno è una versione 1.2 stabile. C'è qualcosa di veramente mantenuto là fuori?
Guss,

4
Ad essere onesti, questi non sono grandi progetti, quindi dovresti aspettarti sempre meno aggiornamenti in C3P0 / DBCP e il tempo passa.
wwadge,

7

Dbcp è pronto per la produzione se configurato correttamente.

Ad esempio, viene utilizzato su un sito Web commerciale di 350000 visitatori / giorno e con pool di 200 connessioni.

Gestisce molto bene i timeout a condizione che sia configurato correttamente.

La versione 2 è in corso e ha un background che la rende affidabile poiché sono stati affrontati molti problemi di produzione.

Lo usiamo per la nostra soluzione di server batch e ha eseguito centinaia di batch che funzionano su milioni di linee nel database.

I test delle prestazioni eseguiti dal pool tomcat jdbc mostrano prestazioni migliori rispetto a cp30.


UBIK LOAD PACK - Stiamo usando DBCP 1.4 e stiamo correndo in continui blocchi del nostro singolo batch con 10000 record. Stiamo usando Spring Batch + JSR 352 e stiamo pensando di passare a HikariCP. Quando dici che 100 di batch funzionano senza intoppi, vuoi dire che funziona con DBCP 2.xo qualsiasi altra versione? Inoltre, ti dispiacerebbe condividere le configurazioni? La nostra configurazione è maxActive = 150, minIdle = 15, maxIdle = 75, initialSize = 15 ma non ho visto gli hang andare via. Non stiamo usando alcuna validationQuery o testOnBorrow / testOnReturn. Mi consiglia di usarlo?
Yogendra,

4

Ho appena finito di perdere un giorno e mezzo con DBCP. Anche se sto usando l'ultima versione di DBCP, ho riscontrato esattamente gli stessi problemi di j pimmel . Non consiglierei affatto DBCP, in particolare è l'abilità di lanciare connessioni dal pool quando il DB scompare, la sua incapacità di riconnettersi quando il DB ritorna e la sua incapacità di aggiungere dinamicamente oggetti di connessione nel pool (si blocca per sempre lettura di un socket I / O JDBCconnect post)

Sto passando a C3P0 ora. L'ho usato in progetti precedenti e ha funzionato ed eseguito come un fascino.


4

c3p0 è buono quando stiamo usando progetti di mutithreading. Nei nostri progetti abbiamo utilizzato simultaneamente più esecuzioni di thread utilizzando DBCP, quindi abbiamo ottenuto il timeout della connessione se abbiamo utilizzato più esecuzioni di thread. Quindi siamo andati con la configurazione c3p0.


3

Una buona alternativa che è facile da usare è DBPool .

"Un'utilità di pooling delle connessioni al database basata su Java, che supporta la scadenza basata sul tempo, la memorizzazione nella cache delle istruzioni, la convalida della connessione e una facile configurazione mediante un gestore di pool."

http://www.snaq.net/java/DBPool/


Ho confrontato DBPool vs BoneCP. DBPool rende getConnection () sincronizzato tra le altre cose ed è molto più lento di BoneCP (vedi: jolbox.com/forum/viewtopic.php?f=3&t=175 ).
wwadge,

3

Ci siamo imbattuti in una situazione in cui dovevamo introdurre il pool di connessioni e avevamo davanti a noi 4 opzioni.

  • DBCP2
  • C3P0
  • Tomcat JDBC
  • HikariCP

Abbiamo effettuato alcuni test e confronti in base ai nostri criteri e abbiamo deciso di optare per HikariCP. Leggi questo articolo che spiega perché abbiamo scelto HikariCP.


1

Per implementare il C3P0 nel modo migliore, controlla questa risposta

C3P0 :

Per le applicazioni aziendali, C3P0 è l'approccio migliore. C3P0 è una libreria di facile utilizzo per aumentare i driver JDBC tradizionali (basati su DriverManager) con origini dati associabili a JNDI, comprese le origini dati che implementano il collegamento e il pool di istruzioni, come descritto dalle specifiche jdbc3 e dall'estensione std jdbc2. C3P0 ha anche gestito in modo robusto le disconnessioni dei DB e le riconnessioni trasparenti al riavvio, mentre DBCP non ha mai recuperato le connessioni se il collegamento è stato rimosso da sotto di esso.

Questo è il motivo per cui c3p0 e altri pool di connessioni hanno anche preparato delle cache delle istruzioni: ciò consente al codice dell'applicazione di evitare di gestire tutto ciò. Le istruzioni sono generalmente conservate in un pool LRU limitato, quindi le istruzioni comuni riutilizzano un'istanza PreparedStatement.

Peggio ancora, DBCP stava restituendo gli oggetti Connection all'applicazione per la quale il trasporto sottostante si era rotto. Un caso d'uso comune per c3p0 è la sostituzione del pool di connessioni DBCP standard incluso con Apache Tomcat. Spesso, un programmatore si imbatte in una situazione in cui le connessioni non vengono correttamente riciclate nel pool di connessioni DBCP e c3p0 è una valida sostituzione in questo caso.

Negli aggiornamenti attuali C3P0 ha alcune caratteristiche brillanti. quelli sono indicati qui sotto:

ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setMinPoolSize();
dataSource.setMaxPoolSize();
dataSource.setMaxIdleTime();
dataSource.setMaxStatements();
dataSource.setMaxStatementsPerConnection();
dataSource.setMaxIdleTimeExcessConnections();

In questo caso, il pool di dimensioni massime e minime definisce i limiti della connessione, il che significa la velocità minima e massima consentita da questa applicazione. MaxIdleTime()definire quando rilascerà la connessione inattiva.

DBCP :

Anche questo approccio è buono ma presenta alcuni inconvenienti come il timeout della connessione e il rilascio della connessione. C3P0 è buono quando stiamo usando progetti di mutithreading. Nei nostri progetti abbiamo utilizzato simultaneamente più esecuzioni di thread utilizzando DBCP, quindi abbiamo ottenuto il timeout della connessione se abbiamo utilizzato più esecuzioni di thread. Quindi siamo andati con la configurazione c3p0. Non consiglierei affatto DBCP, in particolare è l'abilità di lanciare connessioni dal pool quando il DB scompare, la sua incapacità di riconnettersi quando il DB ritorna e la sua incapacità di aggiungere dinamicamente oggetti di connessione al pool (si blocca per sempre lettura di un socket I / O JDBCconnect post)

Grazie :)


1

la mia raccomandazione è

hikari> druid> UCP> c3p0> DBCP

Si basa su ciò che ho testato - 20190202, nel mio ambiente di test locale (4 GB mac / mysql in docker / pool minSize = 1, maxSize = 8), hikari può servire 1024 thread x 1024 volte per ottenere connessioni, tempo medio per ogni thread per finire è 1 o 2 milioni di secondi, mentre c3p0 può servire solo 256 thread x 1024 volte e il tempo medio per ogni thread è già di 21 milioni di secondi. (512 thread non riusciti).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.