独家首发! java助力mycat实现动态添加数据源, 实现SaaS新增租户秒登独立数据库

Posted 李昊轩的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了独家首发! java助力mycat实现动态添加数据源, 实现SaaS新增租户秒登独立数据库相关的知识,希望对你有一定的参考价值。

这里先简单介绍一下背景, 防止看官迷糊

  • 首先手上有一个项目要实现分库, 技术选型为mycat
  • A(运维系统), B(SaaS系统)
  • 目标效果(时间顺序 -> 1 -> 2 -> 3 -> 4):
    1. 管理员在A系统新增租户时
    2. 新建并初始化新租户的数据库
    3. java程序自动在mycat的配置中添加新增租户的配置
    4. 向mycat发送reload命令, 失败自动触发重试机制.
    5. 新租户直接在B系统登录成功.

由于我怀疑File这个类的在mac和linux的native方法有略微区别, 导致了了之前文件没办法rename的bug, 所以这里写的有点笨重, 但是上线时间紧迫就不做修改了, 大家凑合着.

  private static void addMycatConfig(String no, String configPath, String configFileName) throws Exception 
        String rawStr = "    <dataNode name=\\"%s\\" dataHost=\\"localhost1\\" database=\\"%s\\" />";
        String lineInserted = String.format(rawStr, no, CustomerDbService.getDbNameByCustomerId(no));
        String tempPath = configPath + "schematemp.xml";
        File tempFile = new File(tempPath);
        File realConfigFile = new File(configPath + configFileName);
        BufferedReader br = new BufferedReader(new FileReader(realConfigFile));
        BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile));
        String line;
        while ((line = br.readLine()) != null) 
            bw.write(line);
            bw.newLine();
            if (line.trim().startsWith("<schema")) 
                bw.write(lineInserted);
                bw.newLine();
            
        
        bw.flush();
        realConfigFile.renameTo(new File(configPath + "schema_backup_" + System.currentTimeMillis() + ".xml"));
        tempFile.renameTo(new File(configPath + configFileName));

    

reload代码简单发下, 充实策略就是简简单单的开启线程, 注意一下别重复开启重试就好.

 String jdbcUrl = CustomerDbService.getMycatDbUrlFromConfig();
 String username = ApplicationConfig.getInstance().getConfig(CustomerDbService.MYCAT_MANAGE_USER, "");
 String passwd = ApplicationConfig.getInstance().getConfig(CustomerDbService.MYCAT_MANAGE_PWD, "");
 conn = DriverManager.getConnection(jdbcUrl, username, passwd);
 Statement statement = conn.createStatement();
 String refreshCommand = "reload @@config_all;";
 statement.execute(refreshCommand);
 statement.close();

mycat 配置样例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <schema name="saas_logical_db" checkSQLschema="false" sqlMaxLimit="100" dataNode="default" />
        <dataNode name="80008" dataHost="localhost1" database="diy_80008" />
    <dataNode name="20010" dataHost="localhost1" database="diy_20010" />
    <dataNode name="20001" dataHost="localhost1" database="diy_20001" />
    <dataNode name="90001" dataHost="localhost1" database="diy_90001" />
    <dataNode name="default" dataHost="localhost1" database="default_route_db" />
    <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" 
        dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="host1" url="xxx.internal.cn-east-3.mysql.rds.myhuaweicloud.com:3306" user="xxxx" password="xxxx">
        </writeHost>
    </dataHost>
</mycat:schema>

以上是关于独家首发! java助力mycat实现动态添加数据源, 实现SaaS新增租户秒登独立数据库的主要内容,如果未能解决你的问题,请参考以下文章

使用CGLib动态代理jdbc原生类来实现应用层无感知的proxy层面的SaaS分库支持

使用CGLib动态代理jdbc原生类来实现应用层无感知的proxy层面的SaaS分库支持

java短信验证码功能怎么实现,全网独家首发!

java格式化字符串%s个数不确定,全网独家首发!

java和前端哪个好就业,全网独家首发!

Android Jetpack架构组件(入门教程及进阶实战)独家首发