请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

Nacos集群存储信息到mysql问题

Nacos集群启动成功,后台配置的是mysql5.6+的一主两从,以实现主从复制的配置。在Nacos的配置文件中,我把slave节点放在了db.url.0中,在控制台测试写入一个配置信息,数据写入到了第一个实例的slave节点,这个是什么原因造成的?

正在回答 回答被采纳积分+3

2回答

大目 2019-11-05 20:35:51

您好,我简单看了下源码,感觉不可以。

相关代码:

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根本不会看哪个实例能写,哪个不能写。你可以按照上面贴的几段代码,在我上面贴的几段代码方法的第一行,都打上断点调试一下。

祝您学习愉快!

0 回复 有任何疑惑可以回复我~
  • 提问者 岁月中的程序猿 #1
    那这样来说,nacos中的配置mysql现在只能默认把db.url.0设置成Master的,账号密码既要是root的,但是这样一来后面的Mysql主从集群的意义就不大了啊,当主节点宕机的时候,用的又是root权限,除非当时就锁表不然依然可以把数据插入到从库。这样就没法玩了。。。
    回复 有任何疑惑可以回复我~ 2019-11-05 21:19:36
  • 大目 回复 提问者 岁月中的程序猿 #2
    主从可以切换的。主挂了时,从可以晋升成主。
    回复 有任何疑惑可以回复我~ 2019-11-05 21:51:39
提问者 岁月中的程序猿 2019-11-05 17:55:29

检查了下,是我自己的问题,只要我限制了从库的只读属性,就没有这个问题了。老师,这个Nacos可以在配置文件上直接标明主从的关系吗?

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信