Slick + HikariCP + Play导致Postgres在经常重新启动Play后用尽了连接

问题描述 投票:0回答:1

我正在使用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

我的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",

Application.conf

我的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.
    }
  }
}

Play应用

在我玩的游戏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
  } 
}

我尝试了许多不同的配置,但似乎都无法解决我面临的泄漏连接问题。

postgresql playframework connection-pooling slick hikaricp
1个回答
0
投票

当您需要将其作为依赖项时,您将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]

   ...
}

https://github.com/playframework/play-samples/blob/2.8.x/play-scala-slick-example/app/models/PersonRepository.scala#L15

另请参见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] {
}
© www.soinside.com 2019 - 2024. All rights reserved.