推荐的连接池
Java应用推荐使用DBCP。
Java代码实例:
public BasicDataSource rdsDataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setUrl(rdsUrl);
ds.setUsername(userName);
ds.setPassword(passWord);
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setInitialSize(initialSize);
ds.setMaxActive(maxActive);
ds.setMaxIdle(maxActive - 5);
ds.setMaxWait(maxWait);
ds.setPoolPreparedStatements(false);
ds.setDefaultAutoCommit(true);
ds.setValidationQuery("select 1");
ds.setTestWhileIdle(true);
ds.setTestOnBorrow(false);
ds.setTestOnReturn(false);
ds.setTimeBetweenEvictionRunsMillis(180000);
ds.setMinEvictableIdleTimeMillis(3600000);
ds.setNumTestsPerEvictionRun(10);
ds.setRemoveAbandoned(true);
ds.setRemoveAbandonedTimeout(300);
return ds;
}
Spring配置示例:
<bean id="petaDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://${petadata.db.ipport}/xxx" />
<property name="username" value="xxx" />
<property name="password" value="xxx" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="5" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="3000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="180000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="3600000" />
<property name="validationQuery" value="SELECT 1" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 关闭PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="false" />
<property name="numTestsPerEvictionRun" value="5" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="300" />
</bean>
最佳实践
- 首先确认您是否采用连接池访问Hybdrid DB for MySQL?如不是采用连接池访问,请改为连接池方式(dbcp、druid、c3p0等)。
- 你的应用是否是多线程访问Hybdrid DB for MySQL,线程之间是否共享使用Connection对象?如有,请修改,最好不要在多线程间共享使用Connection对象,实现方法请参考下面sample示例代码。
- 最好加入重试机制,保证查询访问的可用性,实现方法请参考下面sample示例代码。
static int MAX_RETRY_TIME = 3;
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
boolean executeSuccess = false;
int retryTime = 0;
while (!executeSuccess && retryTime < MAX_RETRY_TIME) {
try {
if (conn == null || conn.isClosed()) {
// Get connection from data source.
conn= dataSource.getConnection();
}
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
// your logic ...
executeSuccess = true;
} catch () {
log...
retryTime++;
} finally {
try {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (Throwable t) {
logging...
}
}
}
if (!executeSuccess) {
log failure ….
)