Конфигурация 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}
}
}
}
}
И ваш класс-обертка БД должен направлять запросы по умолчанию или только для чтения.