长期以来,Connector/J 提供了一种有效的方法来为集群或源-源复制部署在多个 MySQL 服务器实例之间分配读/写负载。您可以动态配置负载平衡连接,而不会中断服务。进程内事务不会丢失,如果任何应用程序试图使用该特定服务器实例,也不会生成应用程序异常。
负载平衡是在服务器连接的初始设置阶段通过以下连接 URL 配置的,其格式与 MySQL 连接的通用 JDBC URL类似,但有专门的方案:
jdbc:mysql:loadbalance://[host1][:port],[host2][:port][,[host3][:port]]...[/[database]] »
[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]
有两个与此功能关联的配置属性:
loadBalanceConnectionGroup
– 这提供了对来自不同来源的连接进行分组的能力。这允许您以您选择的任何组合在单个类加载器中管理这些 JDBC 源。如果它们使用相同的配置,并且您希望将它们作为一个逻辑组来管理,请为它们指定相同的名称。这是管理的关键属性:如果不为 定义名称(字符串)loadBalanceConnectionGroup
,则无法管理连接。所有共享相同loadBalanceConnectionGroup
值的负载平衡连接,无论应用程序如何创建它们,都将被一起管理。ha.enableJMX
– 当你定义一个时,管理连接的能力就会暴露出来loadBalanceConnectionGroup
;但如果您想在外部管理它,请通过将此属性设置为 来启用 JMXtrue
。这启用了 JMX 实现,它公开了连接组的管理和监视操作。此外,使用-Dcom.sun.management.jmxremote
JVM 标志启动您的应用程序。然后,您可以使用 JMX 客户端(例如jconsole
.
使用正确的连接属性建立连接后,可以使用许多监视属性:
当前活动主机数。
当前活动的物理连接计数。
当前活动的逻辑连接计数。
创建的逻辑连接总数。
总交易数。
还可以执行以下管理操作:
添加主机。
删除主机。
JMX 接口
com.mysql.cj.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&ha.enableJMX=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.cj.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
然后就可以开始了。主Test
类将由 列出jconsole
。选择它并单击
连接。然后您可以导航到该
com.mysql.cj.jdbc.jmx.LoadBalanceConnectionGroupManager
bean。此时可以点击各种操作,查看返回结果。
如果您现在有一个额外的 MySQL 实例在端口 3309 上运行,您可以确保 Connector/J 开始使用它,方法addHost()
是使用在
jconsole
. 请注意,这些操作可以动态执行,而无需停止应用程序运行。
有关负载平衡和故障转移组合的更多信息,请参阅 第 9.5 节,“高级负载平衡和故障转移配置”。
使用 DNS SRV 配置负载平衡
有关详细信息,请参阅第 6.14 节“支持 DNS SRV 记录”。