1. 程式人生 > >LoadBalance和FailOver配置

LoadBalance和FailOver配置

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。