Connector/J提供了负载均衡来配合Mysql集群及多主集群部署,当尝试在多服务间平衡负载,驱动必须决定在什么时候交换服务是安全的,在事务中做交换,可能带来问题,不要弄丢状态信息是很重要的,根据这个原因,Connector/J 只会在以下条件满足才会选择一个新的服务:
1.在事务边界内(事务必须明确的提交或回滚了)
2.一个连接异常发生了(SQL State starting with “08”)
3.当SQLException匹配了用户定义的条件,使用了由loadBalanceSQLStateFailover, loadBalanceSQLExceptionSubclassFailover 或loadBalanceExceptionChecker属性定义的拓展点
第三个条件围绕着Connector/J 5.1.13介绍的三个新的属性,它允许你控制由SQL异常造成的FailOver
- loadBalanceExceptionChecker --loadBalanceExceptionChecker属性是关键,它采用了完全匹配com.mysql.jdbc.LoadBalanceExceptionChecker接口的类名,这个接口十分简单,你只需要试下下面的方法:
public boolean shouldExceptionTriggerFailover(SQLException ex)
传入一个SQLException 返回一个bool值,true:触发FailOver ,false:不触发
你可以实现这个接口来满足自己的业务逻辑,在处理mysql集群一些短暂错误时,也许有用,当给定buffer越界,下面一小段代码表明使用:
public class NdbLoadBalanceExceptionChecker
extends StandardLoadBalanceExceptionChecker {
public boolean shouldExceptionTriggerFailover(SQLException ex) {
return super.shouldExceptionTriggerFailover(ex)
|| checkNdbException(ex);
}
private boolean checkNdbException(SQLException ex){
// Have to parse the message since most NDB errors
// are mapped to the same DEMC.
return (ex.getMessage().startsWith("Lock wait timeout exceeded") ||
(ex.getMessage().startsWith("Got temporary error")
&& ex.getMessage().endsWith("from NDB")));
}
}
上述代码继承了 com.mysql.jdbc.StandardLoadBalanceExceptionChecker,有一些方便的小捷径,内置在里面,对于那些想通过属性进行控制的,无需写java代码。默认实现使用了两个属性loadBalanceSQLStateFailover 和loadBalanceSQLExceptionSubclassFailover.
- loadBalanceSQLStateFailover --允许你定义一个逗号分隔的SQLStat代码前缀,和SQLException形成对比。如果前缀匹配,failover触发。如果一个SQL异常由"00",或者 "12345"打头,将触发failover
loadBalanceSQLStateFailover=00,12345
- loadBalanceSQLExceptionSubclassFailover --可以被用于连接loadBalanceSQLStateFailover和它自己,如果你希望某些异常子类触发failover,只需提供一个以逗号分隔的完全匹配的类名和接口名列表。例如:你想所有的SQLTransientConnectionExceptions异常触发failover,你需要指定
loadBalanceSQLExceptionSubclassFailover=java.sql.SQLTransientConnectionException
虽然前面列举的三个故障转移条件适用于大多数情况,如果autocommit可用,Connector/J不会重新负载,而是继续使用相同的物理连接,这会产生问题,特别是loadbalance被适用于从节点间只读负载。然而,Connector/J可以在一系列Statement执行后配置再平衡。如果autocommit可用,这个功能将取决于以下属性:
- loadBalanceAutoCommitStatementThreshold --定义了可以触发物理连接交换的Statement的数量,默认值是0,保留autoCommit=true并且永远不平衡的行为
- loadBalanceAutoCommitStatementRegex --语句必须匹配的正则表达式,默认值空,匹配所有的Statement,使用如下属性将导致Connector/J 再平衡,当第三个Stament包含字符串"test"
loadBalanceAutoCommitStatementThreshold=3
loadBalanceAutoCommitStatementRegex=.*test.*
loadBalanceAutoCommitStatementRegex在一些场景下能提高可用性,你的服务可以使用临时表,服务端session状态变量,或者一个状态: 在造成数据丢失或其他问题的进程处理完成之前让驱动交换物理连接,这让你确定一个触发规则来决定什么时候安全的进行failover。