Skip to content

开发篇:1.0 客户端连接配置

momo edited this page Jan 4, 2021 · 2 revisions

URL连接参数及连接池配置

1、连接Mycat url的关键参数说明:

useServerPrepStmts=false&rewriteBatchedStatements=false 它们的作用是:

  • useServerPrepStmts

    是否开启预编译参数:Mycat内部是伪支持prepare,内部最终会将prepare语句变为普通语句计算路由后转发给MySQL。无论useServerPrepStmts是true或false, 驱动的 prepare用法上并无差异,主要还是从下面3点考虑该值的设置:

     1、安全:true时,数据更安全,可以防止SQL注入。
    
     2、性能:true时,会涉及到额外的编码转换和prepare交互命令,性能不及false.
    
     3、功能:false时,不支持blob字段,会有乱码问题.
    
  • rewriteBatchedStatements

    是否启用批量执行:1676版本之前的Mycat不支持该值设置为true,务必设置成false,若误设置为true会引起不必要的包乱序问题。最新的1676版本,支持该值为true。下面说明为false时,insert/update/delete语句的不同之处:

    1、insert语句依然是批量提交。比如100 个insert语句,会变成insert into customer(id,name) values(),(),......()这种语句,然后做一次性批量提交。

    2、update和delete语句将采用逐条提交。比如100 个update或delete组成的批量SQL需要jdbc驱动提交100次,相比之下该参数为true时仅需提交1次。

2、批量执行例子

Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(
					"jdbc:mysql://127.0.0.1:8086/TESTDB?useServerPrepStmts=true&rewriteBatchedStatements=false&user=root&password=123");
			pstmt = conn.prepareStatement("insert into customer(id,name) values(?,?)");

			for (int i = 0; i < 100; i++) {
				pstmt.setString(1, String.valueOf(i));
				pstmt.setString(2, String.valueOf(i));
			    pstmt.addBatch();
			}
			pstmt.executeBatch();

3、连接池采用druid连接池,建议spring配置:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <!-- 基本属性 url、user、password -->
        <property name="url" value="jdbc:mysql://127.0.0.1:8066/TESTDB? rewriteBatchedStatements=false&amp;socketTimeout=30000&amp;connectTimeout=3000" />
        <property name="username" value="root" />
        <property name="password" value="123" />
        <!-- 配置初始化大小、最小、最大 -->
        <property name="maxActive" value="30" />
        <property name="initialSize" value="5" />
        <property name="minIdle" value="5" />
        <!-- maxWait获取连接等待超时的时间 -->
        <property name="maxWait" value="60000" />

        <!-- timeBetweenEvictionRunsMillis间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <!-- minEvictableIdleTimeMillis一个连接在池中最小空闲的时间,单位是毫秒-->
        <property name="minEvictableIdleTimeMillis" value="1000000" />
        <property name="validationQuery" value="SELECT 1" />
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="true" />
         <property name="keepAlive" value="true" />
    </bean>
说明:

1、必须配置空闲检查testWhileIdle和归还检查testOnReturn。空闲检查是为了应对连接因为超过30分钟空闲超时时间被mycat主动kill掉,归还检查是为了应对连接出现异常或者已经不可用后,依然归还到连接池。

2、keepAlive 必现配置为true,参考https://github.com/alibaba/druid/wiki/KeepAlive_cn

3、(timeBetweenEvictionRunsMillis + minEvictableIdleTimeMillis)之和应小于mycat默认空闲保留时间30分钟,即1800000ms. 建议timeBetweenEvictionRunsMillis 等于60s即60000,minEvictableIdleTimeMillis等于100s即1000000.

4、mycat的默认空闲时间30分钟,可以通过修改server.xml里面的idleTimeout属性值,比如改成1个小时:

<property name="idleTimeout">600000</property>

综述,通过上面的设置,基本上能解决日常遇到的批量执行、包乱序问题、连接被关闭问题。