Mysql-JDBC配置LoadBalance協議
Mysql-JDBC長期以來提供了有效的手段在MySql叢集、多主Replication部署的情況下分發讀寫負載,自從mysql-jdbc 5.1.3以來,你可以在不停用服務的情況下動態配置loadBalance連線,程序中的事務不丟失,例項不會發生異常。
loadBalance的配置協議如下:
jdbc:mysql:loadbalance://[host1][:port],[host2][:port][,[host3][:port]]...[/[database]] » [?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]
有兩個配置屬性和這個功能相關:
-
loadBalanceConnectionGroup:提供了從不同源進行組連線的能力,用同一個類載入器載入你選擇的資料來源,如果他們有相同的配置,而你想將他們按照邏輯上的單租管理,那麼給他們統一命名。這是管理的關鍵點:如果你沒有給一個loadBalanceConnectionGroup命名,你就不能管理這些連結。所有的loadBalance連線分享同一個組的值,不管應用怎麼建立他們,都會被統一管理
-
loadBalanceEnableJMX:當你定義一個loadBalanceConnectionGroup,管理連線的能力將被暴露出來,如果你想通過外部管理,通過JMX這是屬性為true,這將開啟JMX管理和監控連線組的能力,除此之外,使用-Dcom.sun.management.jmxremote這個引數啟動專案,你可以使用JMX工具,如jconsole,執行你的操作管理連線。
一旦一個連線被用作使用正確的連線屬性,一系列的監控屬性將會可用:
- Current active host count. 當前存活主機數
- Current active physical connection count. 當前存活物理連線數
- Current active logical connection count. 當前存活邏輯連線數
- Total logical connections created. 總建立的邏輯連線數
- Total transaction count. 總事務數
以下的管理操作也可以被執行:
- Add host. 向叢集中新增機器
- Remove host. 從叢集中移除機器
JMX介面:com.mysql.jdbc.jmx.LoadBalanceConnectionGroupManagerMBean,有以下的方法:
- int getActiveHostCount(String group);
- int getTotalHostCount(String group);
- long getTotalLogicalConnectionCount(String group);
- long getActiveLogicalConnectionCount(String group);
- long getActivePhysicalConnectionCount(String group);
- long getTotalPhysicalConnectionCount(String group);
- long getTotalTransactionCount(String group);
- void removeHost(String group, String host) throws SQLException;
- void stopNewConnectionsToHost(String group, String host) throws SQLException;
- void addHost(String group, String host, boolean forExisting);
- String getActiveHostsList(String group);
- String getRegisteredConnectionGroups();
getRegisteredConnectionGroups()返回在類載入時定義的所有連線組名
你可以使用如下程式碼測試連線:
public class Test {
private static String URL = "jdbc:mysql:loadbalance://" +
"localhost:3306,localhost:3310/test?" +
"loadBalanceConnectionGroup=first&loadBalanceEnableJMX=true";
public static void main(String[] args) throws Exception {
new Thread(new Repeater()).start();
new Thread(new Repeater()).start();
new Thread(new Repeater()).start();
}
static Connection getNewConnection() throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection(URL, "root", "");
}
static void executeSimpleTransaction(Connection c, int conn, int trans){
try {
c.setAutoCommit(false);
Statement s = c.createStatement();
s.executeQuery("SELECT SLEEP(1) /* Connection: " + conn + ", transaction: " + trans + " */");
c.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static class Repeater implements Runnable {
public void run() {
for(int i=0; i < 100; i++){
try {
Connection c = getNewConnection();
for(int j=0; j < 10; j++){
executeSimpleTransaction(c, i, j);
Thread.sleep(Math.round(100 * Math.random()));
}
c.close();
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
在編譯後,應用可以使用 -Dcom.sun.management.jmxremote這個引數啟動,來確保遠端管理jconsole可以被啟用,測試的主方法將會被jconsole列出,選擇this.單機Connect,你可以看到com.mysql.jdbc.jmx.LoadBalanceConnectionGroupManager 這個bean,同時,你可以點選變數選項,並且檢查結果集。
如果你再3309上額外運行了一個mysql例項,你可以通過jconsole確保Connector/J成功使用 addHost()新增它,記住這些操作無需停止服務,都是動態更改。
想檢視更多loadbalance和failover的機制,請檢視:
https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-usagenotes-j2ee-concepts-load-balancing-failover.html