Postgres Slaves/Read 副本的 Scala Slick 配置

Scala Slick configuration for Postgres Slaves/Read Replicas

我正在尝试将我的 Scala 应用程序连接到由一个主节点和 3 个 slaves/read 副本组成的 Postgres 集群。我的 application.conf 今天看起来像这样:

slick {
  dbs {
    default {
      driver = "com.company.division.db.ExtendedPgDriver$"
      db {
        driver = "org.postgresql.Driver"
        url = "jdbc:postgresql://"${?DB_ADDR}":"${?DB_PORT}"/"${?DB_NAME}
        user = ${?DB_USERNAME}
        password = ${?DB_PASSWORD}
      }
    }
  }
}

基于Postgres' documentation,我可以将主从全部定义为一体JDBC URL,这将给我一些故障转移能力,像这样:

jdbc:postgresql://host1:port1,host2:port2/database

但是,如果我想通过读写能力分离我的连接,我必须定义两个 JDBC URL,如下所示:

jdbc:postgresql://node1,node2,node3/database?targetServerType=master
jdbc:postgresql://node1,node2,node3/database?targetServerType=preferSlave&loadBalanceHosts=true

如何在 Slick 中定义两个 JDBC URL?我应该在 slick.dbs 下定义两个单独的实体,还是我的 slick.dbs.default.db 实体可以定义多个 URL?

Daniel Westheide's blog post 找到了答案。总而言之,可以使用数据库包装器 class 和提供特定规则的自定义效果类型来控制只读查询的定向位置与写入查询的定向位置。

那么您的 slick 文件将如下所示:

slick {
  dbs {
    default {
      driver = "com.yourdomain.db.ExtendedPgDriver$"
      db {
        driver = "org.postgresql.Driver"
        url = "jdbc:postgresql://"${?DB_PORT_5432_TCP_ADDR}":"${?DB_PORT_5432_TCP_PORT}"/"${?DB_NAME}
        user = ${?DB_USERNAME}
        password = ${?DB_PASSWORD}
      }
    }
    readonly {
      driver = "com.yourdomain.db.ExtendedPgDriver$"
      db {
        driver = "org.postgresql.Driver"
        url = ${DB_READ_REPLICA_URL}
        user = ${?DB_USERNAME}
        password = ${?DB_PASSWORD}
      }
    }
  }
}

这取决于您的数据库包装器 class 将查询路由到 'default' 或 'readonly'