Opcje pulowania połączeń z JDBC: DBCP vs C3P0


312

Jaka jest najlepsza dostępna biblioteka pul połączeń dla Java / JDBC?

Rozważam 2 głównych kandydatów (darmowy / open-source):

Dużo o nich czytałem na blogach i innych forach, ale nie mogłem podjąć decyzji.

Czy istnieją jakieś odpowiednie alternatywy dla tych dwóch?

Odpowiedzi:


181

DBCP jest nieaktualny i nie ma jakości produkcyjnej. Jakiś czas temu przeprowadziliśmy wewnętrzną analizę tych dwóch, tworząc testowe urządzenie, które generowało obciążenie i współbieżność z nimi dwoma, aby ocenić ich przydatność w rzeczywistych warunkach życia.

DBCP konsekwentnie generował wyjątki w naszej aplikacji testowej i starał się osiągnąć poziomy wydajności, które C3P0 był w stanie obsłużyć bez żadnych wyjątków.

C3P0 również solidnie obsługiwał rozłączenia DB i przezroczyste ponowne połączenia po wznowieniu, podczas gdy DBCP nigdy nie odzyskał połączeń, jeśli łącze zostało usunięte spod niego. Co gorsza, DBCP zwracał obiekty Connection do aplikacji, w której uszkodzony został transport bazowy.

Od tego czasu korzystaliśmy z C3P0 w 4 głównych aplikacjach konsumenckich o dużym obciążeniu i nigdy nie oglądaliśmy się za siebie.

AKTUALIZACJA: Okazuje się, że po wielu latach siedzenia na półce lud Apache Commons wyprowadził DBCP ze stanu uśpienia i teraz jest to ponownie aktywnie rozwijany projekt. Dlatego mój oryginalny post może być nieaktualny.

To powiedziawszy, nie doświadczyłem jeszcze wydajności tej nowej, ulepszonej biblioteki, ani nie słyszałem, aby była de facto w żadnej z najnowszych aplikacji.


2
Dzięki! Co powiesz na sugerowaną alternatywę Proxool? Obecna wersja Hibernacji zawiera zarówno c3p0, jak i Proxool.
Dema

Nie próbowaliśmy Proxool, ale na pewno to sprawdzę teraz :)
j pimmel

5
c3p0 ma pewne wady. czasami nie obsługuje szczytów połączeń.
Janning

3
wiele się zmieniło od 4 lat, kiedy po raz pierwszy opublikowałeś tę odpowiedź, czy możesz dodać aktualizację udostępniającą obecny scenariusz, jeśli to możliwe?
Rajat Gupta,

13
Bardzo polecam HikariCP , ale potem pomogłem go napisać.
brettw

177

Zapraszam do wypróbowania BoneCP - jest darmowy, open source i szybszy niż dostępne alternatywy (zobacz sekcję dotyczącą testów porównawczych).

Uwaga: Jestem autorem, więc możesz powiedzieć, że jestem stronniczy :-)

AKTUALIZACJA: Według stanu na marzec 2010 r., Nadal około 35% szybciej niż nowa przepisana pula Apache DBCP („tomcat jdbc”). Zobacz link do dynamicznego testu porównawczego w sekcji testów porównawczych.

Aktualizacja nr 2: (grudzień '13) Po 4 latach na szczycie jest teraz znacznie szybszy konkurent: https://github.com/brettwooldridge/HikariCP

Aktualizacja nr 3: (wrzesień '14) Proszę uważać BoneCP za przestarzały w tym momencie, zalecamy przejście na HikariCP .

Aktualizacja # 4: (kwiecień '15) - Nie mam już domeny jolbox.com


1
Naprawdę chciałbym uzyskać rozwiązanie problemu przy użyciu BoneCP jako źródła danych Tomcat. Główny problem, jaki miałem z tym, to to, że wymagało to zajęć BoneCP w lib tom tomcat, a także klas log4j i google. W ten sposób pule połączeń działały - (nie działało w WAR) - jednak kolidowało to z ustawieniem log4j Tomcat i uniemożliwiało jakiekolwiek wyjście dziennika z aplikacji, która była łamaczem ...
j pimmel

1
To brzmi jak problem z log4j bardziej niż cokolwiek innego. Napisz do mnie na forum.jolbox.com, a pomogę ci jak najszybciej go wyśledzić.
wwadge

3
1up, BoneCP jest genialny. Przełączono z C3P0. Pozwoliło mi to nawet usunąć moją zależność od remiksu log4jdbc, ponieważ pozwala on na wylogowanie instrukcji po wyjęciu z pudełka!
poddaje się

68
+1 za aktualizowanie o czymś, czego nie napisałeś, że jest szybszy!
CorayThan

1
@AndrewScottEvans Prawdopodobnie najlepiej powrócić do wersji v0.7.1
wwadge

16

Miałem problemy z DBCP, gdy upłynęły limity czasu połączeń, więc wypróbowałem c3p0. Zamierzałem wydać to do produkcji, ale potem rozpocząłem testy wydajności. Odkryłem, że c3p0 działał okropnie. Nie mogłem go skonfigurować tak, aby w ogóle działał dobrze. Znalazłem to dwa razy wolniej niż DBCP.

Następnie spróbowałem puli połączeń Tomcat .

To było dwa razy szybsze niż c3p0 i naprawiłem inne problemy, które miałem z DBCP. Spędziłem dużo czasu na badaniu i testowaniu 3 pul. Moja rada, jeśli wdrażasz w Tomcat, to skorzystaj z nowej puli JDBC Tomcat.


14

Czy w przypadku problemu z automatycznym ponownym połączeniem z DBCP ktoś próbował użyć następujących 2 parametrów konfiguracyjnych?

validationQuery="Some Query"

testOnBorrow=true

Jeśli chodzi o dokumentację , testOnBorrowma wartość domyślną true, więc jeśli validationQueryjest zdefiniowana, DBCP przetestuje każde połączenie przed przekazaniem go do aplikacji.
dma_k 17.10.11


12

Używam DBCP od kilku lat w produkcji. Jest stabilny, przetrwa restart serwera DB. Po prostu skonfiguruj to poprawnie. Wymaga jedynie podania kilku parametrów, więc nie bądź leniwy. Oto fragment naszego systemowego kodu produkcyjnego, który zawiera parametry, które jawnie ustawiliśmy, aby działały:

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

Oto kilka artykułów, które pokazują, że DBCP ma znacznie wyższą wydajność niż C3P0 lub Proxool. Również z własnego doświadczenia c3p0 ma kilka fajnych funkcji, takich jak przygotowywanie puli instrukcji i jest bardziej konfigurowalny niż DBCP, ale DBCP jest po prostu szybszy w każdym środowisku, w którym go używałem.

Różnica między dbcp a c3p0? Absolutnie niczego! (Blog programistów Sakai) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

Zobacz także podobne do artykułu JavaTech „Showdown Pool Connection” w komentarzach na blogu.


4
szybciej w środowiskach jednowątkowych, być może wadliwy i niestabilny i po prostu zepsuty gdziekolwiek indziej.

7

Inna alternatywa, Proxool, jest wspomniana w tym artykule .

Być może będziesz w stanie dowiedzieć się, dlaczego Hibernacja pakuje c3p0 do swojej domyślnej implementacji puli połączeń?


7

Niestety wszystkie są nieaktualne. DBCP został niedawno zaktualizowany, pozostałe dwa mają 2-3 lata, z wieloma nierozstrzygniętymi błędami.


To prawda - ostatnie wydanie C3PO (wersja wstępna 0.9) pochodzi z maja 2007 r. Najnowsza wersja Proxool (wersja wstępna 0.9) pochodzi z sierpnia 2008 r. Ostatnia wersja DBCP pochodzi również z kwietnia 2007 r., Ale przynajmniej stabilna wersja 1.2. Czy jest tam coś naprawdę utrzymanego?
Guss,

4
Szczerze mówiąc, nie są to duże projekty, dlatego należy spodziewać się coraz mniej aktualizacji w C3P0 / DBCP, a czas mija.
wwadge,

7

Dbcp jest gotowy do produkcji, jeśli jest odpowiednio skonfigurowany.

Jest on wykorzystywany na przykład na stronie handlowej o wydajności 350000 odwiedzających dziennie i pulach 200 połączeń.

Bardzo dobrze radzi sobie z przekroczeniem limitu czasu, pod warunkiem, że poprawnie go skonfigurujesz.

Wersja 2 jest w toku i ma tło, dzięki czemu jest niezawodna, ponieważ rozwiązano wiele problemów związanych z produkcją.

Używamy go do naszego rozwiązania serwera wsadowego i uruchomiono setki partii, które działają na milionach linii w bazie danych.

Testy wydajności uruchomione przez pulę tomcat jdbc pokazują, że ma lepszą wydajność niż cp30.


UBIK LOAD PACK - Korzystamy z DBCP 1.4 i ciągle się zawieszamy w pojedynczej partii z 10000 rekordami. Używamy Spring Batch + JSR 352 i zastanawiamy się nad przejściem na HikariCP. Kiedy mówisz, że 100 partii działa płynnie, masz na myśli, że działa z DBCP 2.x lub jakąkolwiek inną wersją? Czy mógłbyś również udostępnić konfiguracje? Nasza konfiguracja to maxActive = 150, minIdle = 15, maxIdle = 75, initialSize = 15, ale nie widziałem zawieszeń. Nie korzystamy z żadnego sprawdzania poprawności ani testOnBorrow / testOnReturn. Czy polecasz go używać?
Yogendra,

4

Właśnie skończyłem marnować półtora dnia z DBCP. Mimo że korzystam z najnowszej wersji DBCP, napotkałem dokładnie takie same problemy, jak j pimmel . W ogóle nie poleciłbym DBCP, szczególnie jego umiejętność wyrzucania połączeń z puli, gdy DB zniknie, jej niezdolność do ponownego połączenia, gdy DB wróci, i brak możliwości dynamicznego dodawania obiektów połączeń z powrotem do puli (wisi na zawsze na czytnik po wejściu JDBCconnect I / O)

Teraz przełączam się na C3P0. Użyłem tego w poprzednich projektach i działało i działało jak urok.


4

c3p0 jest dobry, gdy korzystamy z projektów wielowątkowych. W naszych projektach korzystaliśmy jednocześnie z wielu wykonań wątków za pomocą DBCP, a następnie przekroczyliśmy limit czasu połączenia, jeśli korzystaliśmy z większej liczby wątków. Więc poszliśmy z konfiguracją c3p0.


3

Dobrą alternatywą, która jest łatwa w użyciu, jest DBPool .

„Oparte na Javie narzędzie do pulowania połączeń z bazą danych, obsługujące wygaśnięcie czasu, buforowanie instrukcji, sprawdzanie poprawności połączenia i łatwą konfigurację za pomocą menedżera puli”.

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


Przeprowadziłem testy porównawcze DBPool vs BoneCP. DBPool sprawia, że ​​getConnection () jest synchronizowany między innymi i jest znacznie wolniejszy niż BoneCP (patrz: jolbox.com/forum/viewtopic.php?f=3&t=175 ).
wwadge

3

Natrafiliśmy na sytuację, w której musieliśmy wprowadzić pulę połączeń i mieliśmy przed sobą 4 opcje.

  • DBCP2
  • C3P0
  • Tomcat JDBC
  • HikariCP

Przeprowadziliśmy kilka testów i porównań w oparciu o nasze kryteria i zdecydowaliśmy się na HikariCP. Przeczytaj ten artykuł, który wyjaśnia, dlaczego wybraliśmy HikariCP.


1

Aby najlepiej wdrożyć C3P0, sprawdź tę odpowiedź

C3P0 :

W przypadku aplikacji korporacyjnych najlepszym rozwiązaniem jest C3P0. C3P0 to łatwa w użyciu biblioteka do rozszerzania tradycyjnych sterowników JDBC (opartych na DriverManager) o źródła danych, które można powiązać z JNDI, w tym źródła danych, które implementują łączenie połączeń i instrukcji, zgodnie z opisem specyfikacji jdbc3 i rozszerzenia std jdbc2. C3P0 również solidnie obsługuje rozłączanie DB i przezroczyste ponowne łączenie po wznowieniu, podczas gdy DBCP nigdy nie odzyskuje połączeń, jeśli łącze zostanie zdjęte spod niego.

Dlatego właśnie c3p0 i inne pule połączeń również mają przygotowane pamięci podręczne instrukcji - pozwala to kodowi aplikacji uniknąć zajmowania się tym wszystkim. Instrukcje są zwykle przechowywane w pewnej ograniczonej puli LRU, więc często używane instrukcje ponownie wykorzystują instancję PreparedStatement.

Co gorsza, DBCP zwracał obiekty Connection do aplikacji, w której uszkodzony został transport bazowy. Typowym przypadkiem użycia dla c3p0 jest zastąpienie standardowej puli połączeń DBCP dołączonej do Apache Tomcat. Często programista napotyka sytuację, w której połączenia nie są poprawnie przetwarzane w puli połączeń DBCP, a c3p0 jest w tym przypadku cennym zamiennikiem.

W aktualnych aktualizacjach C3P0 ma kilka genialnych funkcji. podano poniżej:

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

Tutaj maksymalny i minimalny rozmiar puli definiują granice połączenia, co oznacza, jak minimalne i maksymalne połączenie będzie przyjmować ta aplikacja. MaxIdleTime()określić, kiedy zwolni bezczynne połączenie.

DBCP :

To podejście jest również dobre, ale ma pewne wady, takie jak przekroczenie limitu czasu połączenia i ponowne wydanie połączenia. C3P0 jest dobry, gdy korzystamy z projektów wielowątkowości. W naszych projektach korzystaliśmy jednocześnie z wielu wykonań wątków za pomocą DBCP, a następnie przekroczyliśmy limit czasu połączenia, jeśli korzystaliśmy z większej liczby wątków. Więc poszliśmy z konfiguracją c3p0. W ogóle nie poleciłbym DBCP, szczególnie jego umiejętność wyrzucania połączeń z puli, gdy DB zniknie, jej niezdolność do ponownego połączenia, gdy DB wróci, i brak możliwości dynamicznego dodawania obiektów połączeń z powrotem do puli (wisi na zawsze na czytnik po wejściu JDBCconnect I / O)

Dzięki :)


1

moje zalecenie to

hikari> druid> UCP> c3p0> DBCP

Opiera się na tym, co przetestowałem - 20190202, w moim lokalnym środowisku testowym (4 GB mac / mysql w oknie dokowanym / puli minSize = 1, maxSize = 8), hikari może dostarczyć 1024 wątki x 1024 razy, aby uzyskać połączenia, średni czas dla każdego wątku zakończenie to 1 lub 2 miliony sekund, podczas gdy c3p0 może obsłużyć tylko 256 wątków x 1024 razy, a średni czas dla każdego wątku wynosi już 21 milionów sekund. (512 wątków nie powiodło się).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.