Squeryl - HikariCP - mySql - 将读取流量分配给从站

Squeryl - HikariCP - mySql - Distributing Read Traffic to Slaves

我正在尝试按照 http://dev.mysql.com/doc/connector-j/en/connector-j-master-slave-replication-connection.html 中列出的步骤进行操作,其中指出

To enable this functionality, use the com.mysql.jdbc.ReplicationDriver class when configuring your application server's connection pool

来自 https://github.com/brettwooldridge/HikariCP - 它说

HikariCP will attempt to resolve a driver through the DriverManager based solely on the jdbcUrl

那么这个配置就够了吗?

db.default.url=jdbc:mysql:replication ...

Squeryl 有许多数据库适配器;但我的理解是这些是无关的? http://squeryl.org/api/index.html#org.squeryl.adapters.MySQLInnoDBAdapter

抱歉加载关键字 - 我只是不太确定我需要关注的地方

谢谢 布伦特

Squeryl 提供了不同的 MySQL 适配器,因为 innodb 支持引用键,而 myisam 不支持。看起来你所做的应该在连接池级别处理,所以我认为你的 Squeryl 配置不会有影响。

我从未为复制 MySQL 配置 Hikari,但如果它需要替代 JDBC 驱动程序,如果您能提供 JDBC URL 一切正常。我猜 Hikari 的默认功能是选择普通的 MySQL JDBC 驱动程序,除非您另有说明。幸运的是,Hikari 有很多 config options 包括设置特定 driverClassName.

的能力

复制允许不同的 URL:

jdbc:mysql:replication://[server1],[server2],[server2]/[database]

我从未尝试过,但我认为这将解析为 ReplicationDriver。

我发现自己又回到了这里 - 请注意,hikari 不支持复制驱动程序。

https://github.com/brettwooldridge/HikariCP/issues/625#issuecomment-251613688

MySQL Replication Driver simply does NOT work together with HikariCP.

https://groups.google.com/forum/#!msg/hikari-cp/KtKgzR8COrE/higEHoPkAwAJ

... nobody running anything resembling a mission critical application takes MySQL's driver-level replication support seriously.

对于 2020 年达到这个目标的人,Hikari 使用

com.mysql.jdbc.jdbc2.optional.MysqlDataSource

作为数据源。如果我看一下上面的代码class。它有一个方法名为 connect which returns Connection instance.

protected Connection getConnection(Properties props) throws SQLException {
    String jdbcUrlToUse = null;
    if (!this.explicitUrl) {
        StringBuffer jdbcUrl = new StringBuffer("jdbc:mysql://");
        if (this.hostName != null) {
            jdbcUrl.append(this.hostName);
        }

        jdbcUrl.append(":");
        jdbcUrl.append(this.port);
        jdbcUrl.append("/");
        if (this.databaseName != null) {
            jdbcUrl.append(this.databaseName);
        }

        jdbcUrlToUse = jdbcUrl.toString();
    } else {
        jdbcUrlToUse = this.url;
    }

    Properties urlProps = mysqlDriver.parseURL(jdbcUrlToUse, (Properties)null);
    urlProps.remove("DBNAME");
    urlProps.remove("HOST");
    urlProps.remove("PORT");
    Iterator keys = urlProps.keySet().iterator();

    while(keys.hasNext()) {
        String key = (String)keys.next();
        props.setProperty(key, urlProps.getProperty(key));
    }

    return mysqlDriver.connect(jdbcUrlToUse, props);
}

其中 mysqlDriver

的实例
protected static final NonRegisteringDriver mysqlDriver;

如果我检查 NonRegisteringDriver 的连接方法 class。看起来像这样

public Connection connect(String url, Properties info) throws SQLException {
    if (url != null) {
        if (StringUtils.startsWithIgnoreCase(url, "jdbc:mysql:loadbalance://")) {
            return this.connectLoadBalanced(url, info);
        }

        if (StringUtils.startsWithIgnoreCase(url, "jdbc:mysql:replication://")) {
            return this.connectReplicationConnection(url, info);
        }
    }

    Properties props = null;
    if ((props = this.parseURL(url, info)) == null) {
        return null;
    } else if (!"1".equals(props.getProperty("NUM_HOSTS"))) {
        return this.connectFailover(url, info);
    } else {
        try {
            com.mysql.jdbc.Connection newConn = ConnectionImpl.getInstance(this.host(props), this.port(props), props, this.database(props), url);
            return newConn;
        } catch (SQLException var6) {
            throw var6;
        } catch (Exception var7) {
            SQLException sqlEx = SQLError.createSQLException(Messages.getString("NonRegisteringDriver.17") + var7.toString() + Messages.getString("NonRegisteringDriver.18"), "08001", (ExceptionInterceptor)null);
            sqlEx.initCause(var7);
            throw sqlEx;
        }
    }
}

看了代码,好像是支持的。直到现在我还没有尝试过。将尝试通过个人经验让您知道。从代码上看,直接可行。