Các tùy chọn gộp nhóm kết nối với JDBC: DBCP vs C3P0


312

Thư viện tổng hợp kết nối tốt nhất có sẵn cho Java / JDBC là gì?

Tôi đang xem xét 2 ứng cử viên chính (miễn phí / nguồn mở):

Tôi đã đọc rất nhiều về họ trên blog và các diễn đàn khác nhưng không thể đưa ra quyết định.

Có bất kỳ lựa chọn thay thế có liên quan đến hai?

Câu trả lời:


181

DBCP đã hết hạn và không phải là cấp sản xuất. Một thời gian trước, chúng tôi đã tiến hành phân tích nội bộ của hai người, tạo ra một vật cố thử nghiệm tạo ra tải và đồng thời chống lại hai để đánh giá sự phù hợp của họ trong điều kiện thực tế.

DBCP luôn tạo ra các ngoại lệ trong ứng dụng thử nghiệm của chúng tôi và đấu tranh để đạt được mức hiệu suất mà C3P0 có khả năng xử lý mà không có bất kỳ ngoại lệ nào.

C3P0 cũng xử lý mạnh mẽ việc ngắt kết nối DB và kết nối lại minh bạch trong sơ yếu lý lịch trong khi DBCP không bao giờ khôi phục các kết nối nếu liên kết được lấy ra từ bên dưới nó. Tệ hơn nữa là DBCP đã trả lại các đối tượng Kết nối cho ứng dụng mà giao thông cơ bản đã bị hỏng.

Kể từ đó, chúng tôi đã sử dụng C3P0 trong 4 ứng dụng web tiêu dùng nặng và không bao giờ nhìn lại.

CẬP NHẬT: Hóa ra sau nhiều năm ngồi trên kệ, dân gian Apache Commons đã đưa DBCP ra khỏi trạng thái ngủ đông và bây giờ, một lần nữa, một dự án được phát triển tích cực. Do đó, bài viết gốc của tôi có thể bị lỗi thời.

Điều đó đang được nói, tôi chưa trải nghiệm hiệu suất của thư viện nâng cấp mới này, cũng chưa nghe nói về việc nó không thực tế trong bất kỳ khuôn khổ ứng dụng nào gần đây.


2
Cảm ơn! Làm thế nào về sự thay thế Proxool được đề xuất? Phiên bản hiện tại của Hibernate đi kèm với cả c3p0 và Proxool.
Dema

Chúng tôi chưa thử Proxool nhưng tôi chắc chắn sẽ kiểm tra ngay bây giờ :)
j pimmel

5
c3p0 có một số nhược điểm. đôi khi nó không thể xử lý các đỉnh kết nối.
JANNING

3
mọi thứ đã thay đổi rất nhiều kể từ 4 năm đầu tiên khi bạn đăng câu trả lời này, bạn có thể thêm một bản cập nhật chia sẻ kịch bản hiện tại không, nếu có thể?
Rajat Gupta

13
Tôi đánh giá cao HikariCP , nhưng sau đó tôi đã giúp viết nó.
brettw 16/11/13

177

Tôi mời bạn dùng thử BoneCP - nó miễn phí, nguồn mở và nhanh hơn các lựa chọn thay thế có sẵn (xem phần điểm chuẩn).

Tuyên bố miễn trừ trách nhiệm: Tôi là tác giả nên bạn có thể nói tôi thiên vị :-)

CẬP NHẬT: Tính đến tháng 3 năm 2010, vẫn nhanh hơn khoảng 35% so với nhóm Apache DBCP ("tomcat jdbc") được viết lại. Xem liên kết điểm chuẩn động trong phần điểm chuẩn.

Cập nhật # 2: (13 tháng 12) Sau 4 năm đứng đầu, giờ đây đã có một đối thủ cạnh tranh nhanh hơn nhiều: https://github.com/brettwooldridge/HikariCP

Cập nhật # 3: (14 tháng 9) Vui lòng xem xét BoneCP không được chấp nhận tại thời điểm này, khuyên bạn nên chuyển sang HikariCP .

Cập nhật số 4: (15 tháng 4) - Tôi không còn sở hữu tên miền jolbox.com


1
Sẽ thực sự thích nhận được sự cố khi sử dụng BoneCP làm Nguồn dữ liệu Tomcat. Vấn đề chính tôi gặp phải là vấn đề này là nó yêu cầu các lớp BoneCP trong thư mục lib của tomcat, cũng như các lớp log4j và google. Việc này làm cho các nhóm kết nối hoạt động - (nó không hoạt động trong khi ở WAR) - tuy nhiên nó đã mâu thuẫn với cài đặt log4j của Tomcat và ngăn chặn mọi đầu ra nhật ký từ ứng dụng, đó là một công cụ giải quyết ...
j pimmel

1
Điều này có vẻ như một vấn đề log4j nhiều hơn bất cứ điều gì khác. Hãy gửi cho tôi một dòng trên forum.jolbox.com và tôi sẽ giúp bạn theo dõi nó càng sớm càng tốt.
wwadge

3
1up, BoneCP thật tuyệt vời. Chuyển từ C3P0. Nó thậm chí còn cho phép tôi loại bỏ sự phụ thuộc của mình vào log4jdbc-remix, vì nó cho phép câu lệnh đăng xuất khỏi hộp!
phụ 2/211

68
+1 để cập nhật về nội dung bạn không viết nhanh hơn!
CorayThan

1
@AndrewScottEvans Có lẽ tốt nhất để trở lại v0.7.1
wwadge

16

Tôi đã gặp sự cố với DBCP khi kết nối hết thời gian nên tôi đã thử c3p0. Tôi sẽ phát hành nó để sản xuất nhưng sau đó bắt đầu thử nghiệm hiệu suất. Tôi thấy rằng c3p0 thực hiện khủng khiếp. Tôi không thể cấu hình nó để thực hiện tốt tất cả. Tôi thấy nó chậm gấp đôi DBCP.

Sau đó tôi đã thử kết nối Tomcat .

Tốc độ này nhanh gấp đôi so với c3p0 và đã khắc phục các sự cố khác mà tôi gặp phải với DBCP. Tôi đã dành rất nhiều thời gian để điều tra và thử nghiệm 3 hồ bơi. Lời khuyên của tôi nếu bạn đang triển khai lên Tomcat là sử dụng nhóm JDBC Tomcat mới.


14

Đối với sự cố tự động kết nối lại với DBCP, bạn đã thử sử dụng 2 tham số cấu hình sau chưa?

validationQuery="Some Query"

testOnBorrow=true

Đối với tài liệu , testOnBorrowcó giá trị mặc định true, do đó, nếu validationQueryDBCP được xác định sẽ kiểm tra mọi kết nối trước khi nó được chuyển đến ứng dụng.
dma_k


12

Đã sử dụng DBCP trong một vài năm nay trong sản xuất. Nó ổn định, sống sót khi khởi động lại máy chủ DB. Chỉ cần cấu hình nó đúng cách. Nó chỉ yêu cầu một số tham số được chỉ định vì vậy đừng lười biếng. Dưới đây là đoạn trích từ mã sản xuất hệ thống của chúng tôi liệt kê các tham số mà chúng tôi đặt rõ ràng để làm cho nó hoạt động:

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

Dưới đây là một số bài viết cho thấy DBCP có hiệu suất cao hơn đáng kể so với C3P0 hoặc Proxool. Ngoài ra, theo kinh nghiệm của riêng tôi, c3p0 có một số tính năng hay, như tổng hợp câu lệnh đã chuẩn bị và có cấu hình cao hơn DBCP, nhưng DBCP nhanh hơn trong mọi môi trường tôi đã sử dụng.

Sự khác biệt giữa dbcp và c3p0? Hoàn toàn không có gì! (Blog của nhà phát triển Sakai) http://bloss.nyu.edu/bloss/nrm216/sakaidelic/2007/12/difference_b between_dbcp_and_c3.html

Xem thêm bài viết tương tự với bài viết "Kết nối hồ bơi kết nối" của JavaTech trong các bình luận trên bài đăng trên blog.


4
nhanh hơn trong các môi trường đơn luồng, có thể, lỗi và không ổn định và chỉ bị hỏng ở bất kỳ nơi nào khác.

7

Một lựa chọn khác, Proxool, được đề cập trong bài viết này .

Bạn có thể tìm hiểu lý do tại sao Hibernate bó c3p0 để triển khai nhóm kết nối mặc định của nó?


7

Thật không may, tất cả họ đã hết hạn. DBCP đã được cập nhật một chút gần đây, hai người kia đã 2-3 tuổi, với nhiều lỗi nổi bật.


Đó là sự thật - bản phát hành cuối cùng của C3PO (bản phát hành trước 0,9) là từ tháng 5 năm 2007. Bản phát hành mới nhất của Proxool (bản phát hành trước 0,9) là từ tháng 8 năm 2008. Bản phát hành cuối cùng của DBCP cũng là từ tháng 4 năm 2007, nhưng ít nhất là một phiên bản 1.2 ổn định. Có bất cứ điều gì thực sự được duy trì ngoài đó?
Guss

4
Để công bằng, đây không phải là những dự án lớn, vì vậy bạn nên mong đợi ngày càng ít cập nhật hơn trong C3P0 / DBCP và thời gian trôi qua.
wwadge

7

Dbcp đã sẵn sàng sản xuất nếu được cấu hình đúng.

Ví dụ, nó được sử dụng trên Trang web thương mại với 350000 khách truy cập / ngày và với số lượng 200 kết nối.

Nó xử lý thời gian chờ rất tốt miễn là bạn cấu hình chính xác.

Phiên bản 2 đang được tiến hành và nó có một nền tảng khiến nó đáng tin cậy vì nhiều vấn đề về Sản xuất đã được giải quyết.

Chúng tôi sử dụng nó cho giải pháp máy chủ hàng loạt của chúng tôi và nó đã chạy hàng trăm lô hoạt động trên hàng triệu dòng trong cơ sở dữ liệu.

Các bài kiểm tra hiệu năng được chạy bởi tomcat jdbc pool cho thấy nó có hiệu năng tốt hơn cp30.


UBIK LOAD GÓI - Chúng tôi đang sử dụng DBCP 1.4 và chạy liên tục trong một đợt duy nhất với 10000 hồ sơ. Chúng tôi đang sử dụng Spring Batch + JSR 352 và nghĩ đến việc chuyển sang HikariCP. Khi bạn nói, 100 lô hoạt động trơn tru, bạn có nghĩa là nó chạy với DBCP 2.x hoặc bất kỳ phiên bản nào khác? Ngoài ra, bạn có phiền chia sẻ các cấu hình? Cấu hình của chúng tôi là maxActive = 150, minIdle = 15, maxIdle = 75, initSize = 15 nhưng chưa thấy hang bị mất. Chúng tôi không sử dụng bất kỳ xác thực hoặc testOnBorrow / testOnReturn. Bạn có khuyên bạn nên sử dụng nó?
Yogendra

4

Chỉ cần thực hiện lãng phí một ngày rưỡi với DBCP. Mặc dù tôi đang sử dụng bản phát hành DBCP mới nhất, tôi đã gặp phải chính xác các vấn đề tương tự như j pimmel đã làm. Tôi hoàn toàn không khuyến nghị DBCP, đặc biệt là việc vứt bỏ các kết nối ra khỏi nhóm khi DB biến mất, nó không thể kết nối lại khi DB quay trở lại và không thể tự động thêm các đối tượng kết nối vào hồ bơi (nó bị treo mãi mãi một bài viết Ổ cắm I / O JDBCconnect đọc)

Tôi đang chuyển sang C3P0 ngay bây giờ. Tôi đã sử dụng nó trong các dự án trước đó và nó hoạt động và thực hiện như một nét duyên dáng.


4

c3p0 là tốt khi chúng tôi đang sử dụng các dự án mutithreading. Trong các dự án của chúng tôi, chúng tôi đã sử dụng đồng thời nhiều lần thực thi luồng bằng cách sử dụng DBCP, sau đó chúng tôi có thời gian chờ kết nối nếu chúng tôi sử dụng nhiều lần thực hiện luồng hơn. Vì vậy, chúng tôi đã đi với cấu hình c3p0.


3

Một lựa chọn tốt dễ sử dụng là DBPool .

"Một tiện ích tổng hợp kết nối cơ sở dữ liệu dựa trên Java, hỗ trợ hết hạn dựa trên thời gian, bộ đệm ẩn câu lệnh, xác thực kết nối và cấu hình dễ dàng bằng trình quản lý nhóm."

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


Tôi đã điểm chuẩn DBPool vs BoneCP. DBPool làm cho getConnection () được đồng bộ hóa với những thứ khác và chậm hơn nhiều so với BoneCP (xem: jolbox.com/forum/viewtopic.php?f=3&t=175 ).
wwadge

3

Chúng tôi đã gặp một tình huống cần giới thiệu nhóm kết nối và chúng tôi có 4 tùy chọn trước mặt chúng tôi.

  • DBCP2
  • C3P0
  • JDBC Tomcat
  • HikariCP

Chúng tôi đã thực hiện một số thử nghiệm và so sánh dựa trên các tiêu chí của chúng tôi và quyết định chọn HikariCP. Đọc bài viết này giải thích lý do tại sao chúng tôi chọn HikariCP.


1

Để thực hiện C3P0 theo cách tốt nhất, sau đó kiểm tra câu trả lời này

C3P0 :

Đối với ứng dụng doanh nghiệp, C3P0 là cách tiếp cận tốt nhất. C3P0 là một thư viện dễ sử dụng để tăng các trình điều khiển JDBC truyền thống (dựa trên DriverManager) với DataSource có thể liên kết với JNDI, bao gồm cả DataSource thực hiện Kết nối và khai báo câu lệnh, như được mô tả bởi phần mở rộng jdbc3 spec và jdbc2. C3P0 cũng xử lý mạnh mẽ việc ngắt kết nối DB và kết nối lại minh bạch trong sơ yếu lý lịch trong khi DBCP không bao giờ khôi phục các kết nối nếu liên kết được lấy ra từ bên dưới nó.

Vì vậy, đây là lý do tại sao c3p0 và các nhóm kết nối khác cũng đã chuẩn bị bộ đệm câu lệnh - nó cho phép mã ứng dụng tránh xử lý tất cả điều này. Các câu lệnh thường được lưu giữ trong một số nhóm LRU giới hạn, vì vậy các câu lệnh phổ biến sử dụng lại một thể hiện PreparedStatement.

Tệ hơn nữa là DBCP đã trả lại các đối tượng Kết nối cho ứng dụng mà giao thông cơ bản đã bị hỏng. Trường hợp sử dụng phổ biến cho c3p0 là thay thế nhóm kết nối DBCP tiêu chuẩn đi kèm với Apache Tomcat. Thông thường, một lập trình viên sẽ gặp phải tình huống trong đó các kết nối không được tái chế chính xác trong nhóm kết nối DBCP và c3p0 là sự thay thế có giá trị trong trường hợp này.

Trong các bản cập nhật hiện tại, C3P0 có một số tính năng tuyệt vời. những người được đưa ra dưới đây:

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

Ở đây, max và min poolsize xác định giới hạn của kết nối đó có nghĩa như thế nào tối thiểu và tối đa kết nối ứng dụng này sẽ mất. MaxIdleTime()xác định khi nào nó sẽ giải phóng kết nối nhàn rỗi.

DBCP :

Cách tiếp cận này cũng tốt nhưng có một số nhược điểm như hết thời gian kết nối và thực hiện kết nối. C3P0 là tốt khi chúng tôi đang sử dụng các dự án mutithreading. Trong các dự án của chúng tôi, chúng tôi đã sử dụng đồng thời nhiều lần thực thi luồng bằng cách sử dụng DBCP, sau đó chúng tôi có thời gian chờ kết nối nếu chúng tôi sử dụng nhiều lần thực hiện luồng hơn. Vì vậy, chúng tôi đã đi với cấu hình c3p0. Tôi hoàn toàn không khuyến nghị DBCP, đặc biệt là việc vứt bỏ các kết nối ra khỏi nhóm khi DB biến mất, nó không thể kết nối lại khi DB quay trở lại và không thể tự động thêm các đối tượng kết nối vào hồ bơi (nó bị treo mãi mãi một bài viết Ổ cắm I / O JDBCconnect đọc)

Cảm ơn :)


1

đề nghị của tôi là

hikari> druid> UCP> c3p0> DBCP

Nó dựa trên những gì tôi đã thử nghiệm - 20190202, trong môi trường thử nghiệm cục bộ của tôi (4GB mac / mysql trong docker / pool minSize = 1, maxSize = 8), hikari có thể phục vụ 1024 luồng x 1024 lần để có kết nối, thời gian trung bình cho mỗi luồng để hoàn thành là 1 hoặc 2 triệu giây, trong khi c3p0 chỉ có thể phục vụ 256 luồng x 1024 lần và thời gian trung bình cho mỗi luồng là 21 triệu giây. (512 chủ đề thất bại).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.