Конфигурация Scala Slick для ведомых / читающих реплик Postgres

Я пытаюсь подключить свое приложение Scala к кластеру Postgres, состоящему из одного главного узла и 3 подчиненных / считывающих реплик. Мой 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, я могу определить главного и подчиненных в одном URL JDBC, что даст мне некоторые возможности отработки отказа, например:

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

Однако, если я хочу разделить свои соединения с помощью функций чтения и записи, я должен определить два URls JDBC, например:

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

Как я могу определить два URL JDBC в Slick? Должен ли я определить две отдельные сущности в slick.dbs, или моя сущность slick.dbs.default.db может иметь несколько определенных URL-адресов?

1 ответ

Решение

Нашел ответ в блоге Дэниела Вестхайде. Подводя итог, это можно сделать с помощью класса-обертки БД и пользовательских типов эффектов, которые предоставляют особые правила для управления направлением запросов только для чтения по сравнению с запросами записи.

Тогда ваш гладкий файл будет выглядеть так:

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}
      }
    }
  }
}

И ваш класс-обертка БД должен направлять запросы по умолчанию или только для чтения.

Другие вопросы по тегам