如第 9.3 節〈使用 Connector/J 設定負載平衡〉和對多來源複寫拓撲的支援中所述,Connector/J 為 MySQL Cluster 或多來源部署提供實用的負載平衡實作。相同的實作也用於平衡複寫感知連線的唯讀複本之間的負載。
嘗試平衡多部伺服器之間的工作負載時,驅動程式必須判斷何時可以安全地交換伺服器,例如在交易中途執行此操作可能會導致問題。重要的是不要遺失狀態資訊。因此,Connector/J 只有在發生下列其中一種情況時才會嘗試選取新的伺服器
在交易邊界時 (交易已明確認可或回復)。
遇到通訊例外狀況 (SQL 狀態以 "08" 開頭)。
當
SQLException
符合使用者定義的條件時,使用loadBalanceSQLStateFailover
、loadBalanceSQLExceptionSubclassFailover
或loadBalanceExceptionChecker
屬性定義的延伸點。
第三個條件圍繞三個屬性,可讓您控制哪些 SQLException
會觸發容錯移轉
-
loadBalanceExceptionChecker
-loadBalanceExceptionChecker
屬性確實是關鍵。這需要一個完整類別名稱,該類別名稱實作新的com.mysql.cj.jdbc.ha.LoadBalanceExceptionChecker
介面。此介面非常簡單,您只需要實作下列方法public boolean shouldExceptionTriggerFailover(SQLException ex)
會傳入一個
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"))); } }
上述程式碼會擴充
com.mysql.cj.jdbc.ha.StandardLoadBalanceExceptionChecker
,這是預設實作。對於想要使用屬性來進行一定程度的控制,而無需撰寫 Java 程式碼的人來說,此程式碼內建了一些便利的捷徑。此預設實作會使用其餘兩個屬性:loadBalanceSQLStateFailover
和loadBalanceSQLExceptionSubclassFailover
。 -
loadBalanceSQLStateFailover
- 可讓您定義以逗號分隔的SQLState
代碼前置詞清單,並將SQLException
與之比較。如果前置詞相符,則會觸發容錯移轉。因此,舉例來說,如果指定的SQLException
以 "00" 開頭,或為 "12345",則下列內容會觸發容錯移轉loadBalanceSQLStateFailover=00,12345
-
loadBalanceSQLExceptionSubclassFailover
- 可與loadBalanceSQLStateFailover
一起使用,或單獨使用。如果您希望某些SQLException
子類別觸發容錯移轉,只要提供以逗號分隔的完整類別或介面名稱清單以供檢查即可。例如,如果您希望所有SQLTransientConnectionExceptions
都觸發容錯移轉,您將指定loadBalanceSQLExceptionSubclassFailover=java.sql.SQLTransientConnectionException
雖然先前列舉的三個容錯移轉條件適用於大多數情況,但如果啟用 autocommit
,Connector/J 永遠不會重新平衡,並繼續使用相同的實體連線。當使用負載平衡來跨多個複本分配唯讀負載時,這可能會造成問題。然而,當啟用 autocommit
時,可以設定 Connector/J 在執行一定數量的陳述式後重新平衡。此功能取決於下列屬性
loadBalanceAutoCommitStatementThreshold
– 定義將觸發驅動程式潛在交換實體伺服器連線的相符陳述式數量。預設值 0 會保留啟用autocommit
的連線永遠不會平衡的行為。-
loadBalanceAutoCommitStatementRegex
– 陳述式必須符合的規則運算式。預設值為空白,符合所有陳述式。因此,舉例來說,使用下列屬性會導致 Connector/J 在每個包含字串 「測試」 的第三個陳述式後重新平衡loadBalanceAutoCommitStatementThreshold=3 loadBalanceAutoCommitStatementRegex=.*test.*
loadBalanceAutoCommitStatementRegex
在許多情況下可能很有用。您的應用程式可能會使用暫時表格、伺服器端工作階段狀態變數或連線狀態,在完成處理之前讓驅動程式任意交換實體連線可能會導致資料遺失或其他問題。這可讓您識別只有在安全交換實體連線時才會執行的觸發陳述式。
使用 DNS SRV 設定負載平衡和容錯移轉
如需詳細資訊,請參閱第 6.14 節〈對 DNS SRV 記錄的支援〉。