#高可用连接配置
# 多地址连接配置
在使用驱动连接存在多个节点的YashanDB服务端时,可以配置多个或多组监听地址(host:port)进行连接。
多个监听地址间用
,分隔,连接时根据服务类型(serverType参数)配置对相应节点进行连接。多组监听地址间用
;分隔,同组内的多个监听地址间用,分隔,连接时先在组内根据serverType配置对相应节点进行连接,当组内所有连接均失败后按顺序优先级(越靠前优先级越高)访问下一组。
Note:
- 多组监听地址连接的故障切换效率低于多个监听地址连接,分组主要用于尽可能保障仅通过第一组地址建立数据库连接,请根据实际需求选择是否分组。
- 在共享集群/分布式集群部署中,若已配置SCAN或VIP,直接使用数据库服务端提供的高可用能力即可,无需额外配置多地址连接。
- 配置多地址连接共享集群/分布式集群时:
- 若为单集群部署,驱动会将其所有实例视作主节点。
- 若为主备集群部署,驱动会将主集群的所有实例视作主节点、备集群的所有实例视作备节点。如需在未配置SCAN或VIP的场景下实现负载均衡,可考虑配置多组地址连接并按需指定primaryLoadBalance或standbyLoadBalance,主集群的所有实例为一个组,备集群的所有实例为另一个组。
URL参数格式为:
jdbc:yasdb:serverType://host1:port1,host2:port2;host3:port3,host4:port4/databasename
// serverType=primary|standby时,可以指定poolTimeout
jdbc:yasdb:serverType://host1:port1,host2:port2;host3:port3,host4:port4/databasename?poolTimeout=value
配置项介绍如下:
serverType:多地址连接的连接类型,可选项包括primary、standby、loadBalance、primaryLoadBalance以及standbyLoadBalance。若不指定serverType,在输入多IP时默认采用primary。各类型的详细介绍如下:
serverType 说明 primary 默认类型,可省略。
驱动会按指定监听地址的先后顺序连接节点,并通过执行SELECT * FROM DATABASE_ROLE判断节点角色,保留首次与主节点建立的连接。standby 驱动会按指定监听地址的先后顺序连接节点,并通过执行SELECT * FROM DATABASE_ROLE判断节点角色,保留首次与备节点建立的连接。 loadBalance 驱动会将指定的监听地址随机打乱顺序后进行连接,获取每个节点当前的会话数,选取会话数最小值对应的节点作为目标节点(若最小值存在多个节点则取最先建立连接的节点),保留目标节点的连接并关闭其他连接。 primaryLoadBalance 驱动会将指定的监听地址随机打乱顺序后进行连接,获取每个节点当前的会话数量和角色,选取主节点中会话数最小值对应的节点作为目标节点(若最小值存在多个节点则取最先建立连接的节点),保留目标节点的连接并关闭其他连接。 standbyLoadBalance 驱动会将指定的监听地址随机打乱顺序后进行连接,获取每个节点当前的会话数量和角色,选取备节点中会话数最小值对应的节点作为目标节点(若最小值存在多个节点则取最先建立连接的节点),保留目标节点的连接并关闭其他连接。 poolTimeout:仅可搭配primary或standby类型使用,表示连接超时时间,单位为秒。可选参数,省略时默认为300。在整个连接过程中,即便快速遍历完所有地址且所有地址均未连接成功,系统仍会等待poolTimeout时长后才提示连接失败。
高可用连接配置中的socketTimeout和loginTimeout含义及配置方式与基本连接配置一致,具体请参考基本连接配置-超时时间配置。
URL连接配置示例:
// 示例1:primary + 多个IP/PORT + poolTimeout
jdbc:yasdb:primary://192.168.1.2:1688,192.168.1.3:1688,192.168.1.4:1688/yasdb?poolTimeout=180
// 示例2:standby + 多组IP/PORT + poolTimeout
jdbc:yasdb:standby://192.168.1.2:1688,192.168.1.3:1688;192.168.1.4:1688,192.168.1.5:1688/yasdb?poolTimeout=180
// 示例3:loadBalance + 多个IP/PORT
jdbc:yasdb:loadBalance://192.168.1.2:1688,192.168.1.3:1688,192.168.1.4:1688/yasdb
// 示例4:primaryLoadBalance + 多组IP/PORT
jdbc:yasdb:primaryLoadBalance://192.168.1.2:1688,192.168.1.3:1688;192.168.1.4:1688,192.168.1.5:1688/yasdb
// 示例5:standbyLoadBalance + 多个IP/PORT
jdbc:yasdb:standbyLoadBalance://192.168.1.2:1688,192.168.1.3:1688,192.168.1.4:1688/yasdb
// 示例6:YAC事务扩展能力,单节点连接
jdbc:yasdb://192.168.1.2:1688/yasdb
// 示例7:YAC事务扩展能力,两节点负载均衡连接
jdbc:yasdb:loadBalance://192.168.1.1:1688,192.168.1.2:1688/yasdb
# 透明应用故障转移TAF配置
# TAF相关参数
YashanDB JDBC中存在如下TAF功能相关的URL参数:
| 参数名称 | 数据类型 | 参数说明 |
|---|---|---|
| failover | string | 是否开启TAF,参数值支持ON或OFF,默认为OFF。 * ON:表示开启TAF,当故障发生时应用程序会自动切换到已配置的其他数据库节点。 * OFF:表示关闭TAF,且暂不支持在OFF状态下自动重连当前数据库节点。 |
| failoverType | string | 故障转移的类型,支持NONE、SESSION和SELECT,默认为NONE。 * NONE:表示不使用故障转移。 * SESSION:表示发生故障后重连并重置Statement句柄。 * SELECT:表示在SESSION类型的基础上,切换连接后重新执行因故障而执行出错的SELECT语句(此时,SELECT语句不能为带LOB类型的绑定参数的查询语句),但不支持再对切换前已获取的对象进行二次操作。 |
| failoverMethod | string | 故障转移的方式,该值将决定从主节点到备节点的故障转移速度。 * BASIC:表示在故障转移时再建立连接。 |
| failoverRetries | int | 重试次数,默认值为5。 |
| failoverDelay | int | 重试间隔时间(单位:秒),默认值为1。 |
URL参数格式为:
jdbc:yasdb:serverType://host1:port1,host2:port2;host3:port3,host4:port4/yasdb?key1=value1&key2=value2
URL连接配置示例:
// 示例:primary + 多组IP/PORT + TAF会话级故障转移
// 连接主节点,组内按地址顺序连接;当前组连接失败后按组顺序切换,并在故障发生时重连会话
jdbc:yasdb:primary://192.168.1.2:1688,192.168.1.3:1688;192.168.1.4:1688,192.168.1.5:1688;192.168.1.6:1688,192.168.1.7:1688/yasdb?poolTimeout=180&failover=on&failoverType=session&failoverMethod=basic&failoverRetries=5&failoverDelay=1
配置多组IP/PORT连接时,组内按照serverType类型连接,组间按照顺序优先级访问,例如有3组IP/PORT连接,当前发生TAF的节点在第2组,则先访问第2组其他节点,再访问第1组节点,最后访问第3组节点。
# TAF相关接口
TAF功能相关的接口如下:
| 类 | 返回类型 | 方法 | 参数 | 说明 |
|---|---|---|---|---|
| YasConnection | void | registerTAFCallback(YasFailover yasFailover, Object ctxt) | [1] yasFailover:用户注册实现callbackFn方法的实体类 [2] ctxt:用户想要保存的任何对象 | 注册TAF回调函数的实现类,如果注册了回调函数,failoverRetries和failoverDelay参数不生效,TAF链接失败时不会尝试进行重接。 |
| YasFailover | void | callbackFn (Connection conn, Object ctxt, int type, int event) | [1] conn:当前的链接 [2] ctxt:用户想要保存的任何对象 [3] type:故障转移类型 [4] event:故障转移事件类型, | TAF的回调函数,该方法由应用程序继承实现。目前只支持FO_BEGIN、FO_ERROR、FO_RETRY、FO_END,在FO_ERROR事件中如果返回FO_RETRY则表示再尝试进行一次接接。 |
# 使用示例
当数据库服务端发生故障时,配置了TAF功能的JDBC驱动能够自动重接或切换到活跃实例。切换成功后可能会抛出相关异常,开发人员可以捕获对应的异常信息并根据信息分析判断是否需要执行相应措施(例如回滚事务等)。
异常信息为"The transaction must be rerun.",表示当前行为内触发了TAF且已成功重接,但当前操作处于事务过程中,服务端的事务已经回滚,此时应用层需要执行connection.rollback()并且重新执行事务。
异常信息为"Cannot be safely called repeatedly.",表示当前行为内触发了TAF且已成功重接,此时需要应用层在确保安全的情况下重新执行SQL。
异常信息为"Failover reconnect fail",表示当前行为内触发了TAF,但重接失败。此时应检查网络是否正常、检查数据库是否正常运行。
在事务过程中发生TAF的示例如下:
import java.sql.*;
import java.util.Properties;
public static void main(String[] args) throws Exception {
String className = "com.yashandb.jdbc.Driver";
String url = "jdbc:yasdb://192.168.1.2:1688,192.168.1.3:1688/yasdb?failover=on&failoverType=session&failoverMethod=basic&failoverRetries=100&failoverDelay=15";
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
Class.forName(className);
Connection connection = DriverManager.getConnection(url, info); // 获取接接
connection.setAutoCommit(false); // 开启事务
dealTafInTransaction(connection);
}
private static void dealTafInTransaction(Connection connection) throws SQLException {
try (Statement statement = connection.createStatement()) {
//sql1、sql2、sql3表示事务中需要执行的SQL语句,此处不列示具体内容
String sql1 = "...";
String sql2 = "...";
String sql3 = "...";
try {
statement.execute(sql1);
statement.execute(sql2);
statement.execute(sql3);
connection.commit();//提交事务
} catch (SQLException e) {
connection.rollback();//必须执行rollback,否则后续事务内任何语句或commit操作都将报错
if ("The transaction must be rerun.".equals(e.getMessage())) {// 出现该异常信息说明taf已经重接成功,此时可以选择重新执行整个事务
dealTafInTransaction(connection);
}
throw e;
}
}
}
不在事务过程中发生TAF的示例如下:
private static final String TAF_ERROR_MSG = "Cannot be safely called repeatedly.";
public static void main(String[] args) throws Exception {
String className = "com.yashandb.jdbc.Driver";
String url = "jdbc:yasdb://192.168.1.2:1688,192.168.1.3:1688/yasdb?failover=on&failoverType=session&failoverMethod=basic&failoverRetries=100&failoverDelay=15";
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
Class.forName(className);
Connection connection = DriverManager.getConnection(url, info); // 获取接接
connection.setAutoCommit(true); // 不开启事务
dealTafWithoutTransaction(connection);
}
public static void dealTafWithoutTransaction(Connection connection) throws SQLException {
try (Statement statement = connection.createStatement()) {
//sql1、sql2表示需要执行的SQL语句,此处不列示具体内容
String sql1 = "...";
String sql2 = "...";
try {
statement.execute(sql1);
} catch (SQLException e) {
if (TAF_ERROR_MSG.equals(e.getMessage())) { // 出现该异常信息说明taf已经重接成功,此时可以选择重新执行该语句
statement.execute(sql1);
}
throw e;
}
//对于带参数的SQL语句(假设sql2是一条带参数绑定的SQL语句),若执行过程中发生TAF,无需重复绑定参数
PreparedStatement preparedStatement = connection.prepareStatement(sql2);
preparedStatement.setInt(1,1);
preparedStatement.setString(2,"2");//参数绑定
try {
preparedStatement.execute();
} catch (SQLException e) {
if (TAF_ERROR_MSG.equals(e.getMessage())) {//sql语句执行中发生了taf,只需要重新执行该语句即可,不需要重新进行参数绑定了
preparedStatement.execute();
}
throw e;
}
}
}
# 心跳连接的配置
开启心跳连接能够使得程序更快的检测到正在使用的连接已经异常,从而跳出当前等待返回数据的状态,从而触发后续的操作,例如故障恢复。
心跳连接相关参数如下:
| 参数 | 类型 | 描述 |
|---|---|---|
| heartbeatSwitch | string | 心跳连接是否开启,有ON和OFF两个可选值,默认为ON。 |
| heartbeatSocketTimeout | int | 心跳连接的保活超时时间(单位:秒),默认为60秒。 |
| heartbeatSchedulePeriod | int | 心跳连接的保活间隔时间(单位:秒),默认为20秒。 |
URL连接配置示例:
// 示例:开启心跳连接,并设置心跳响应超时和探测周期
// 每20秒发送一次心跳探测,等待服务端响应的超时时间为60秒
jdbc:yasdb://192.168.1.2:1688/yasdb?heartbeatSwitch=on&heartbeatSocketTimeout=60&heartbeatSchedulePeriod=20

