`
lixjluck
  • 浏览: 101722 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

生产环境数据源c3p0的配置

阅读更多

 前市面上可用的数据源有 3 :c3p0, dbcp, bonecp 。对应一个数据源生产使用,主要注意以下几个点:  

1.    性能

2.    自动重连

3.    安全,目前只有jboss app server内置的数据源支持数据库密码的加密。

 

以下为 c3p0 的配置

1 pool size config ,这个主要看你的应用以及数据库配置,来决定 min,max pool size;另外你也可以做一下性能测试,以寻找一个合适的数值

 

 

<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">    
         <property name="initialPoolSize"><value>10</value></property>  
	  <property name="minPoolSize"><value>5</value></property>  
	  <property name="maxPoolSize"><value>30</value></property>
         <property ame="acquireIncrement"><value>5</value></property>
</bean> 

 

     参考: http://www.mchange.com/projects/c3p0/index.html#basic_pool_configuration

 

2. statement pool size (针对 PrepareStatement

 

<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">  
	      <property name="maxStatements"><value>30</value></property>  
	      <property name="maxStatementsPerConnection"><value>5</value></property>       
</bean>

 

   参考: http://www.mchange.com/projects/c3p0/index.html#configuring_statement_pooling

 

3 、自动重连

  如果在获取连接时抛出异常, c3p0 会捕获此异常,进行重试。

  此功能一般用于生产环境数据库维护时,切换主、备机引起的问题。

 

<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 
      <property name="acquireRetryAttempts"><value>30</value></property>  
      <property name="acquireRetryDelay"><value>1000</value></property>
      <property name="breakAfterAcquireFailur "><value>false</value></property>
</bean> 
 

参考:http://www.mchange.com/projects/c3p0/index.html#configuring_recovery

4、安全性
     在生产环境,访问数据库的密码都是经过加密的,你即使看到,也不能拿来用,那如何把这个加密的密码给c3p0用呢?
     比如,实际数据的密码是pwd, 但配置文件里指定的却是b7220dfdfdf8;这就需要我们在生产环境模式下,去解码,把b7220dfdfdf8还原为pwd。

<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">  
      <!-- c3p0数据源的一个专有属性,只可以存放密码和用户名,详情可以研究它的源码,开源的吗 -->
      <property name="properties">
          <bean class="com.common.DatasourcePropertiesFactory" factory-method="getProperties">
    			<constructor-arg type=" java.lang.String">
    				<value>${jdbc_password_encrypted}</value>
	    		</constructor-arg>
	    		<!-- 生产环境模式 ,才特殊处理加密密码-->
	    		<constructor-arg type="java.lang.String">
	    			<value>${production}</value>
                       </constructor-arg>
             </bean>
	</property>
</bean> 

 

   DatasourcePropertiesFactory的源码:

public class DatasourcePropertiesFactory {

    private static final String PRODUCTION_MODE    = "true";
    private static final String PROP_PASSWORD      = "password";
    private static final String DEFAULT_SECURE_KEY = "secure key";

    public static Properties getProperties(String pwd, String production) throws Exception {
        Properties p = new Properties();      
        // production mode
        if (PRODUCTION_MODE.equalsIgnoreCase(StringUtil.trim(production))) {
            try {
                p.setProperty(PROP_PASSWORD, decode(pwd));
            } catch (Exception e) {     
                throw e;
            }
        }
        return p;
    }

    //以下两个方法参考于jboss的实现
    private static String encode(String secret) throws NamingException, NoSuchAlgorithmException, InvalidKeyException,
                                               NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
        byte[] kbytes = DEFAULT_SECURE_KEY.getBytes();
        SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");

        Cipher cipher;
        cipher = Cipher.getInstance("Blowfish");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encoding = cipher.doFinal(secret.getBytes());
        BigInteger n = new BigInteger(encoding);
        return n.toString(16);
    }

    private static String decode(String secret) throws NoSuchPaddingException, NoSuchAlgorithmException,
                                               InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        byte[] kbytes = DEFAULT_SECURE_KEY.getBytes();
        SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");

        BigInteger n = new BigInteger(secret, 16);
        byte[] encoding = n.toByteArray();
        Cipher cipher = Cipher.getInstance("Blowfish");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decode = cipher.doFinal(encoding);
        return new String(decode);
    }

    public static void main(String[] args) throws NamingException, InvalidKeyException, NoSuchAlgorithmException,
                                          NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
        String secret = "ca";
        System.out.println(encode(secret));
    }
}

---以下无内容。

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics