我正在使用Slick和HikariCP开发用于连接池的Play应用程序。在重新启动Play后,我的开发Postgres服务器用尽了所有连接并显示,
db_1 | 2019-11-19 21:06:46.583 GMT [395] FATAL: remaining connection slots are reserved for non-replication superuser connections
db_1 | 2019-11-19 21:06:46.886 GMT [396] FATAL: remaining connection slots are reserved for non-replication superuser connections
db_1 | 2019-11-19 21:06:48.167 GMT [397] FATAL: remaining connection slots are reserved for non-replication superuser connections
我使用SQL查询SELECT state, COUNT(*) FROM pg_stat_activity GROUP BY state;
进行了监视,似乎确实空闲连接的数量迅速增加。我想解决此问题,以便在开发或生产中不会泄漏连接。
关于如何解决空闲连接泄漏的任何建议?
我的build.sbt
具有以下依赖性,
"com.typesafe.play" %% "play-slick" % "4.0.2",
"com.typesafe.play" %% "play-slick-evolutions" % "4.0.2",
"com.typesafe.slick" %% "slick-codegen" % "3.3.2",
"com.typesafe.slick" %% "slick" % "3.3.2",
"org.slf4j" % "slf4j-nop" % "1.7.26",
"com.typesafe.slick" %% "slick-hikaricp" % "3.3.2",
"org.postgresql" % "postgresql" % "42.2.8",
我的postgres配置存储在我的application.conf
中
slick {
dbs {
default {
profile="slick.jdbc.PostgresProfile$"
db {
connectionPool = "HikariCP" //use HikariCP for our connection pool
profile = "org.postgresql.Driver"
dataSourceClass = "org.postgresql.ds.PGSimpleDataSource" //Simple datasource with no connection pooling. The connection pool has already been specified with HikariCP.
properties = {
serverName = "localhost"
portNumber = "5432"
databaseName = "website"
user = "websiteserver"
password = "397c9140fb0e2424396510b8d6e29a07aa1a92420027d3750ef1faed87bb617a"
}
}
numThreads = 10
connectionTimeout = 6000 // In the hope that this resolves the connection errors.
leakDetectionThreshold=60000 // In the hope that this resolves the connection errors.
}
}
}
在我玩的游戏2.7.3应用中,我使用加载数据库配置,
@Singleton
class PersonRepositoryImpl @Inject() ()(implicit ec: PersonExecutionContext)
extends PersonRepository {
// We want the JdbcProfile for this provider
private val db = Database.forConfig("slick.dbs.default.db")
private val persons = TableQuery[PersonTable]
def create(p: Person)(implicit mc: MarkerContext): Future[PersonData] = db.run {
// Some operations on persons
}
}
我尝试了许多不同的配置,但似乎都无法解决我面临的泄漏连接问题。
当您需要将其作为依赖项时,您将Database.forConfig
称为私有值。您应该利用play-slick
依赖性注入数据库配置提供程序:
@Singleton
class PersonRepository @Inject() (dbConfigProvider: DatabaseConfigProvider)(implicit ec: ExecutionContext) {
// We want the JdbcProfile for this provider
private val dbConfig = dbConfigProvider.get[JdbcProfile]
...
}
另请参见documentation:
虽然您可以通过访问SlickApi手动获取DatabaseConfig实例,但我们为运行时DI用户(Guice,Scaldi,Spring等)提供了一些帮助程序,用于在控制器中获取特定实例。
这里是如何为默认数据库(即,您的配置中名为default的数据库)注入DatabaseConfig实例的示例:
class Application @Inject() (protected val dbConfigProvider: DatabaseConfigProvider, cc: ControllerComponents)(
implicit ec: ExecutionContext
) extends AbstractController(cc)
with HasDatabaseConfigProvider[JdbcProfile] {
}