Воспроизведение — соединения HikariCP не возвращаются в пул

В проекте Play, который имеет два подпроекта, мы пробуем HikariCP, и он, похоже, не освобождает соединения обратно в пул и выдает это исключение:

java.sql.SQLException: Timeout of 30000ms encountered waiting for connection.

Вот что показывает отладка после шести простых запросов:

[DEBUG] c.z.h.p.HikariPool - Before cleanup pool stats pool1 (total=5, inUse=5, avail=0, waiting=1)
[DEBUG] c.z.h.p.HikariPool - After cleanup pool stats pool1 (total=5, inUse=5, avail=0, waiting=1)
[DEBUG] c.z.h.p.HikariPool - Timeout failure pool stats pool1 (total=5, inUse=5, avail=0, waiting=0)
[ERROR] application - Error in datastore operation detected.
java.sql.SQLException: Timeout of 30000ms encountered waiting for connection.
    at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:207) ~[HikariCP-java6-2.0.1.jar:na]
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:93) ~[HikariCP-java6-2.0.1.jar:na]
    at scala.slick.jdbc.JdbcBackend$DatabaseFactoryDef$$anon$3.createConnection(JdbcBackend.scala:47) ~[slick_2.11-2.1.0.jar:0.8.0]
    at scala.slick.jdbc.JdbcBackend$BaseSession.conn$lzycompute(JdbcBackend.scala:397) ~[slick_2.11-2.1.0.jar:0.8.0]
    at scala.slick.jdbc.JdbcBackend$BaseSession.conn(JdbcBackend.scala:397) ~[slick_2.11-2.1.0.jar:0.8.0]
[DEBUG] c.z.h.p.HikariPool - Before cleanup pool stats pool1 (total=5, inUse=4, avail=1, waiting=0)
[DEBUG] c.z.h.p.HikariPool - After cleanup pool stats pool1 (total=5, inUse=4, avail=1, waiting=0)

Мы используем две базы данных Postgres с двумя пулами и версиями:

Play: 2.3.3
Scala: 2.11.1
HikariCP: 2.0.1
Play-hikaricp: 1.4.1
Postgres: 9.3

ОБНОВЛЕНИЕ:

Включение обнаружения утечек (leakDetectionThreshold=10000) генерирует следующие предупреждения:

[WARN] c.z.h.p.LeakTask - Connection leak detection triggered, stack trace follows
java.lang.Exception: null
    at scala.slick.jdbc.JdbcBackend$DatabaseFactoryDef$$anon$3.createConnection(JdbcBackend.scala:47) ~[slick_2.11-2.1.0.jar:0.8.0]
    at scala.slick.jdbc.JdbcBackend$BaseSession.conn$lzycompute(JdbcBackend.scala:397) ~[slick_2.11-2.1.0.jar:0.8.0]
    at scala.slick.jdbc.JdbcBackend$BaseSession.conn(JdbcBackend.scala:397) ~[slick_2.11-2.1.0.jar:0.8.0]
    at scala.slick.jdbc.JdbcBackend$SessionDef$class.prepareStatement(JdbcBackend.scala:152) ~[slick_2.11-2.1.0.jar:0.8.0]
    at scala.slick.jdbc.JdbcBackend$BaseSession.prepareStatement(JdbcBackend.scala:389) ~[slick_2.11-2.1.0.jar:0.8.0]
[WARN] c.z.h.p.LeakTask - Connection leak detection triggered, stack trace follows
java.lang.Exception: null
    at scala.slick.jdbc.JdbcBackend$DatabaseFactoryDef$$anon$3.createConnection(JdbcBackend.scala:47) ~[slick_2.11-2.1.0.jar:0.8.0]
    at scala.slick.jdbc.JdbcBackend$BaseSession.conn$lzycompute(JdbcBackend.scala:397) ~[slick_2.11-2.1.0.jar:0.8.0]
    at scala.slick.jdbc.JdbcBackend$BaseSession.conn(JdbcBackend.scala:397) ~[slick_2.11-2.1.0.jar:0.8.0]
    at scala.slick.jdbc.JdbcBackend$SessionDef$class.prepareStatement(JdbcBackend.scala:152) ~[slick_2.11-2.1.0.jar:0.8.0]
    at scala.slick.jdbc.JdbcBackend$BaseSession.prepareStatement(JdbcBackend.scala:389) ~[slick_2.11-2.1.0.jar:0.8.0]

person centr    schedule 28.10.2014    source источник
comment
Вероятно, это проблема конфигурации Slick, возможно, из-за отложенного выполнения запроса после получения соединения. Я бы предложил включить обнаружение утечек, чтобы увидеть, есть ли потоки, висящие на соединениях, без своевременного возврата их в пул (> 10 секунд).   -  person brettw    schedule 29.10.2014
comment
@brettw: Спасибо. Я обновил вопрос. Что это означает? Я заметил, что у некоторых других пользователей с двумя базами данных/пулами была аналогичная проблема.   -  person centr    schedule 29.10.2014


Ответы (1)


Как я сказал в отчете об ошибке на github, похоже, ответил здесь. Я не разработчик Play/slick, поэтому я не знаю, в чем основная проблема. Но я знаю, что это не ошибка в HikariCP. Закрытые соединения немедленно возвращаются в пул.

Асинхронные системы, такие как Scala, при неправильном использовании при доступе к ресурсам, которые могут блокироваться, могут привести к накоплению ожидающих выполнения задач, которые начинают страдать от тайм-аутов ресурсов. Обычно это обеспечивается отдельными пулами выполнения потоков для блокировки доступа. Я бы ожидал, что такие вещи будут встроены в структуру Slick, но, как я уже сказал выше, я не совсем знаком со Slick.

person brettw    schedule 29.10.2014
comment
закрытие сеансов вручную решило проблему. Я надеюсь, что Slickians включит более простой способ для этого. Спасибо за отличную работу. - person centr; 29.10.2014
comment
@centr Просто интересно, устойчивое ли это решение. Это работало для вас в течение длительного времени? - person Shurik Agulyansky; 14.04.2016