Connector/J 为 MySQL 集群或多源部署提供了有用的负载平衡实现,如 第 9.3 节“使用 Connector/J 配置负载平衡” 和支持多源复制拓扑结构中所述。同样的实现用于平衡只读副本之间的负载,以实现复制感知连接。
当试图平衡多台服务器之间的工作负载时,驱动程序必须确定何时可以安全地交换服务器,例如,在事务中间这样做可能会导致问题。重要的是不要丢失状态信息。出于这个原因,Connector/J 只会在以下情况之一发生时尝试选择新服务器:
在事务边界(事务被显式提交或回滚)。
遇到通信异常(SQL State 以“08”开头)。
当 a
SQLException
匹配用户定义的条件时,使用loadBalanceSQLStateFailover
,loadBalanceSQLExceptionSubclassFailover
或loadBalanceExceptionChecker
属性定义的扩展点。
第三个条件围绕三个属性,它们允许您控制哪个SQLException
触发故障转移:
-
loadBalanceExceptionChecker
-loadBalanceExceptionChecker
财产真的是关键。这需要一个实现新com.mysql.cj.jdbc.ha.LoadBalanceExceptionChecker
接口的完全限定类名。这个接口非常简单,你只需要实现下面的方法:public boolean shouldExceptionTriggerFailover(SQLException ex)
传入A
SQLException
,并返回一个布尔值。的值true
会触发故障转移,false
但不会。您可以使用它来实现您自己的自定义逻辑。这可能有用的一个例子是在使用 MySQL Cluster 时处理瞬态错误,其中某些缓冲区可能会过载。以下代码片段说明了这一点:
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"))); } }
上面的代码 extends
com.mysql.cj.jdbc.ha.StandardLoadBalanceExceptionChecker
,这是默认实现。对于那些希望在不编写 Java 代码的情况下使用属性进行某种程度的控制的人来说,其中内置了一些方便的快捷方式。此默认实现使用剩余的两个属性:loadBalanceSQLStateFailover
和loadBalanceSQLExceptionSubclassFailover
。 -
loadBalanceSQLStateFailover
- 允许您定义以逗号分隔的SQLState
代码前缀列表,a 与之进行SQLException
比较。如果前缀匹配,则触发故障转移。因此,例如,如果给定SQLException
以“00”或“12345”开头,则以下内容将触发故障转移:loadBalanceSQLStateFailover=00,12345
-
loadBalanceSQLExceptionSubclassFailover
- 可以结合使用loadBalanceSQLStateFailover
或单独使用。如果您希望 的某些子类SQLException
触发故障转移,只需提供以逗号分隔的完全限定类或接口名称列表以进行检查。例如,如果您希望全部SQLTransientConnectionExceptions
触发故障转移,您可以指定:loadBalanceSQLExceptionSubclassFailover=java.sql.SQLTransientConnectionException
虽然前面列举的三个故障转移条件适用于大多数情况,但如果autocommit
启用,Connector/J 永远不会重新平衡,并继续使用相同的物理连接。这可能会有问题,特别是当负载平衡用于跨多个副本分配只读负载时。但是,Connector/J 可以配置为在执行一定数量的语句后重新平衡autocommit
(启用时)。此功能取决于以下属性:
loadBalanceAutoCommitStatementThreshold
– 定义将触发驱动程序可能交换物理服务器连接的匹配语句的数量。默认值 0 保留autocommit
启用的连接永远不会平衡的行为。-
loadBalanceAutoCommitStatementRegex
– 语句必须匹配的正则表达式。默认值空白,匹配所有语句。因此,例如,使用以下属性将导致 Connector/J 在每三个包含字符串“ test ”的语句之后重新平衡:loadBalanceAutoCommitStatementThreshold=3 loadBalanceAutoCommitStatementRegex=.*test.*
loadBalanceAutoCommitStatementRegex
在许多情况下都可以证明是有用的。您的应用程序可能会使用临时表、服务器端会话状态变量或连接状态,让驱动程序在处理完成之前任意交换物理连接可能会导致数据丢失或其他问题。这使您可以识别仅在交换物理连接安全时才执行的触发器语句。
使用 DNS SRV 配置负载平衡和故障转移
有关详细信息,请参阅第 6.14 节“支持 DNS SRV 记录”。