您好,我简单看了下源码,感觉不可以。
相关代码:
https://github.com/alibaba/nacos/blob/master/config/src/main/java/com/alibaba/nacos/config/server/service/BasicDataSourceServiceImpl.java
checkMasterWritable方法:
@Override
public boolean checkMasterWritable() {
testMasterWritableJT.setDataSource(jt.getDataSource());
/**
* 防止login接口因为主库不可用而rt太长
*/
testMasterWritableJT.setQueryTimeout(1);
String sql = " SELECT @@read_only ";
try {
Integer result = testMasterWritableJT.queryForObject(sql, Integer.class);
if (result == null) {
return false;
} else {
return result.intValue() == 0 ? true : false;
}
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
return false;
}
}
从这个代码可知,其实就是用 SELECT @@read_only 在玩的……事实上,这个代码没有用到……
顺便吐槽一下这个方法的命名,真的是词不达意。从方法名称看,是说检查master节点是否可写。但其实逻辑写的是检查节点是否master。我觉得改成checkIsMaster才能比较贴切地表达其用意。
在 https://github.com/alibaba/nacos/blob/master/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/MysqlHealthCheckProcessor.java
中,也可以验证这一点。
事实上,上面贴出的第一段代码,目前根本没有用,我估计是个未完成的能力。不过不管怎样,也可以知道,即使是未来,也无法自己指定index。
Nacos真正判断谁是Master还是Slave的代码在这里:com.alibaba.nacos.config.server.service.BasicDataSourceServiceImpl.SelectMasterTask#run:
@Override
public void run() {
if (defaultLog.isDebugEnabled()) {
defaultLog.debug("check master db.");
}
boolean isFound = false;
int index = -1;
for (BasicDataSource ds : dataSourceList) {
index++;
testMasterJT.setDataSource(ds);
testMasterJT.setQueryTimeout(queryTimeout);
try {
testMasterJT
.update(
"DELETE FROM config_info WHERE data_id='com.alibaba.nacos.testMasterDB'");
if (jt.getDataSource() != ds) {
fatalLog.warn("[master-db] {}", ds.getUrl());
}
jt.setDataSource(ds);
tm.setDataSource(ds);
isFound = true;
masterIndex = index;
break;
} catch (DataAccessException e) { // read only
e.printStackTrace(); // TODO remove
}
}
它比较蠢,迭代你配置的数据源list,然后弄个index从-1开始++;
然后用jdbcTemplate去发送SQL:
DELETE FROM config_info WHERE data_id='com.alibaba.nacos.testMasterDB'
然后判断一下,把master的index设置为当前的index。
按照目前的设计,你的db.url.0 就是master,其他是slave。Master根本不会看哪个实例能写,哪个不能写。你可以按照上面贴的几段代码,在我上面贴的几段代码方法的第一行,都打上断点调试一下。
祝您学习愉快!