这个测试的目的是验证当前常用数据库连接池的性能。
testcase
Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.preparedStatement("select 1");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
}
rs.close();
stmt.close();
conn.close();
test config
property | value |
initialSize | 10 |
minPoolSize | 10 |
maxPoolSize | 50 |
测试各种并发场景下执行申请1,000,000(一百万)次总耗时的性能对比。
环境
- OS linux 3.5.0-19-generic X86_64
- CPU XEON E5-2450 双路共16核32物理线程
- Memory 48G
这是一台双路至强CPU的工作站,比我之前在mac book pro上做的测试,更接近真实服务器的运行环境。
JDK 1.6.0_38
数据库连接池 | 1 thread | 2 threads | 5 threads | 10 threads | 20 threads | 50 threads | 100 threads |
druid | 248 | 710 | 1,133 | 1,134 | 905 | 1,107 | 1,468 |
dbcp | 660 | 1,522 | 3,545 | 4,176 | 3,671 | 4,237 | 14,129 |
boneCP | 3,522 | 2,930 | 2,579 | 3,745 | 7,434 | 11,991 | 14,584 |
c3p0 | 4,275 | 9,509 | 3,371 | 10,439 | 13,472 | 19,848 | 36,153 |
proxool | 7,187 | 7,707 | 11,037 | 10,777 | 15,222(Error) | 18,100(Error) | 21,547(Error) |
tomcat-jdbc | 372 | 736 | 1,879 | 1,727 | 1,576 | 1,322 | 12,545 |
jboss-datasource | 1,326 | 1,184 | 2,928 | 3,765 | 3,099 | 3,278 | 10,812 |
JDK 1.7.0_10
数据库连接池 | 1 thread | 2 threads | 5 threads | 10 threads | 20 threads | 50 threads | 100 threads |
druid | 309 | 605 | 1,028 | 947 | 962 | 897 | 1,238 |
dbcp | 924 | 1,461 | 4,062 | 4,030 | 4,908 | 5,505 | 14,517 |
boneCP | 3,047 | 2,055 | 2,549 | 3,821 | 6,367 | 12,865 | 18,832 |
c3p0 | 4,018 | 8,206 | 8,897 | 10,667 | 12,367 | 25,822 | 38,681 |
proxool | 6912 | 4,714 | 4,851 | 11,908 | 16,066(Error) | 19,568(Error) | 18,036(Error) |
tomcat-jdbc | 400 | 740 | 1,811 | 1,707 | 1,618 | 1,624 | 11,905 |
jboss-datasource | 1,369 | 1,105 | 4,002 | 3,089 | 3,483 | 3,665 | 11,782 |
结果分析
- Druid是性能最好的数据库连接池,tomcat-jdbc和druid性能接近。
- proxool在激烈并发时会抛异常,完全不靠谱。在并发10的情况下,会使用11或者12个物理连接。
- c3p0和proxool都相当慢,慢到影响sql执行效率的地步。
- bonecp性能并不优越,采用LinkedTransferQueue并没有能够获得性能提升。
- jboss-datasource虽然稳定,但是性能很糟糕
- boneCP和c3p0完全不遵循minPoolSize的配置,只要有活动请求,就会用到maxPoolSize。
- bonecp和c3p0存在较大并发时使用的物理连接超过maxPoolSize数量,达到maxPoolSize+1