解决io.shardingsphere.core.exception.ShardingException:The URL of JDBC is not supported.异常

一、问题描述

前段时间使用sharding-jdbc对项目进行分库分表操作,使用如下版本的依赖:

        <dependency>
            <groupId>io.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>3.0.0.M3</version>
        </dependency>

在dev和beta环境都可以正常部署及实现。但是将项目部署到preview环境时却报错了,报错信息如下:
报错信息

分析定位问题

当时很疑惑为什么会报不支持jdbc的url的错误。beta和preview环境jdbc的url的区别只是换了数据库服务器的域名和数据库名。并且beta和preview环境,java和tomcat的版本都是一样的。百思不得其解,多次尝试无果后回归日志,从上往下可以看到是io.shardingsphere.core.metadata.datasource.dialect包下的MySQLDataSourceMetaData.java抛出的异常。找到该文件找到源码。源码如下:

package io.shardingsphere.core.metadata.datasource.dialect;

import com.google.common.base.Strings;
import io.shardingsphere.core.exception.ShardingException;
import io.shardingsphere.core.metadata.datasource.DataSourceMetaData;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class MySQLDataSourceMetaData implements DataSourceMetaData {
    private static final int DEFAULT_PORT = 3306;
    private final String hostName;
    private final int port;
    private final String schemeName;
    private final Pattern pattern = Pattern.compile("jdbc:mysql://([a-zA-Z0-9\\-\\.]+):?([0-9]*)/(\\w+);?\\w*");

    public MySQLDataSourceMetaData(String url) {
        Matcher matcher = this.pattern.matcher(url);
        if (matcher.find()) {
            this.hostName = matcher.group(1);
            this.port = Strings.isNullOrEmpty(matcher.group(2)) ? 3306 : Integer.valueOf(matcher.group(2));
            this.schemeName = matcher.group(3);
        } else {
            throw new ShardingException("The URL of JDBC is not supported.", new Object[0]);
        }
    }

    public boolean isInSameDatabaseInstance(DataSourceMetaData dataSourceMetaData) {
        return this.hostName.equals(dataSourceMetaData.getHostName()) && this.port == dataSourceMetaData.getPort();
    }

    public String getHostName() {
        return this.hostName;
    }

    public int getPort() {
        return this.port;
    }

    public String getSchemeName() {
        return this.schemeName;
    }

    public Pattern getPattern() {
        return this.pattern;
    }
}

通过源码可以看出应该是preview环境的jdbc的url的格式和sharding-jdbc要求的正则表达式不匹配所致。
恍然大悟,beta环境使用的jdbc的url类似如下格式:

sharding.jdbc.datasource.db1.url=jdbc:mysql://xxx-xxx.xxx.xxx:3306/xxx_xxx?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false&tinyInt1isBit=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai

而preview环境使用的jdbc的url类似如下格式:

sharding.jdbc.datasource.db1.url=jdbc:mysql://xx-xx_xx_xx.xx.xx:3306/xx_xx_xx?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false&tinyInt1isBit=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai

三、解决问题

通过上面的分析可以看到原来3.0.0.M3版本的shardingsphere不支持URL中数据库服务器域名中带下划线,改为3.1.0版本的问题得到解决。
3.1.0版本jdbc的url的正则表达式为:

private final Pattern pattern = Pattern.compile("jdbc:mysql:(\\w*:)?//([\\w\\-\\.]+):?([0-9]*)/([\\w\\-]+);?\\S*", 2);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffylv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值