Конфигурация BasicDataSource для многопользовательского источника данных
Я реализовал многопользовательскую аренду следующим образом: http://blog.trixi.cz/2012/01/multitenancy-using-spring-and-postgresql/
TL; DR: у меня есть база данных postgres с одной схемой для каждого из моих арендаторов. Я использую java apache dbcp2 для настройки пула соединений. Для каждого арендатора я сохраняю BasicDataSource на карте, и для каждого запроса я ищу источник данных на этой карте, чтобы установить соединение для этого арендатора. Каждый источник данных установил правильный путь для своего арендатора.
Я пытаюсь выяснить возможную конфигурацию пула соединений для этой настройки.
До сих пор я использовал какой-то случайный, явно неправильный конфиг, например:
maxTotal 100
maxIdle 30
maxWaitMillis 10000
testOnBorrow true
testWhileIdle true
validationQuery select 1
minEvitableIdleTimeMillis 300000
timeBetweenEvictionRunsMillis -1
removeAbandonedOnMaintenance true
removeAbandonedOnBorrow true
В postgres у меня есть этот параметр:
max_connections 100
С этой конфигурацией я теперь сталкиваюсь с исключениями:
org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections
Пожалуйста, помогите мне понять:
maxTotal
слишком много, так как он определен для источника данных, которых у меня столько, сколько у меня есть арендаторовmaxTotal
никогда не должен быть больше чемmax_connections
в postgres для этого,n * maxTotal < max_connections
гдеn
это количество арендаторов у меня есть- Я вижу много свободных соединений, но очень мало активных
maxIdle
слишком много слишком высоко - установка
timeBetweenEvictionRunsMillis
в-1
оказывает настройкуminEvictableIdleTimeMillis
быть неиспользованным, так как поток выселения никогда не работает вообще
Итак, мой следующий подход будет выглядеть примерно так:
maxTotal 8
maxIdle 2
minIdle 0
maxWaitMillis 30000
testOnBorrow true
validationQuery select 1
removeAbandonedOnMaintenance true
removeAbandonedOnBorrow true
Поэтому я хочу сохранить одновременные соединения на каждого арендатора, позволяя максимально использовать до 8 соединений. Я также хочу свести к минимуму количество незанятых соединений, чтобы ни один арендатор не держал слишком много соединений.
Здесь возникает еще несколько вопросов:
Нужен ли поток evictor для работы maxIdle? То есть я должен установить timeBetweenEvictionRunsMillis
?
Должен ли я рассмотреть возможность использования другого механизма пула соединений, скажем, pgBouncer? Я думаю, что можно было бы интерпретировать мою настройку как множество отдельных приложений, использующих одну общую базу данных, таким образом, необходимость в pgBouncer...
Есть какой-нибудь нестатический способ настроить мои пулы в соответствии с количеством арендаторов? Скажем, сегодня у меня 20 арендаторов, и, возможно, на следующей неделе у меня будет 40 ...