Play/Slick:SQLTimeoutException:等待连接 1001 毫秒后超时

Play/Slick: SQLTimeoutException: Timeout after 1001ms of waiting for a connection

我用 PostgreSQL 9.4 数据库创建了一个空的(激活器模板 play-scala)Play 2.4.3 应用程序并尝试使用 Slick 3.1.0,但它抛出错误:

play.api.UnexpectedException: Unexpected exception[SQLTimeoutException: Timeout after 1000ms of waiting for a connection.]
    at play.core.server.DevServerStart$$anonfun$mainDev$$anon$$anonfun$get$$anonfun$apply$$anonfun.apply(DevServerStart.scala:165) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$$anon$$anonfun$get$$anonfun$apply$$anonfun.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at scala.Option.map(Option.scala:146) ~[scala-library-2.11.7.jar:na]
    at play.core.server.DevServerStart$$anonfun$mainDev$$anon$$anonfun$get$$anonfun$apply.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$$anon$$anonfun$get$$anonfun$apply.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at scala.util.Success.flatMap(Try.scala:231) ~[scala-library-2.11.7.jar:na]
    at play.core.server.DevServerStart$$anonfun$mainDev$$anon$$anonfun$get.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$$anon$$anonfun$get.apply(DevServerStart.scala:111) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1(Future.scala:24) ~[scala-library-2.11.7.jar:na]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library-2.11.7.jar:na]
    at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40) ~[akka-actor_2.11-2.3.13.jar:na]
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397) ~[akka-actor_2.11-2.3.13.jar:na]
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) ~[scala-library-2.11.7.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) ~[scala-library-2.11.7.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) ~[scala-library-2.11.7.jar:na]
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) ~[scala-library-2.11.7.jar:na]
Caused by: java.sql.SQLTimeoutException: Timeout after 1000ms of waiting for a connection.
    at com.zaxxer.hikari.pool.BaseHikariPool.getConnection(BaseHikariPool.java:227) ~[HikariCP-java6-2.3.7.jar:na]
    at com.zaxxer.hikari.pool.BaseHikariPool.getConnection(BaseHikariPool.java:182) ~[HikariCP-java6-2.3.7.jar:na]
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:93) ~[HikariCP-java6-2.3.7.jar:na]
    at slick.jdbc.hikaricp.HikariCPJdbcDataSource.createConnection(HikariCPJdbcDataSource.scala:12) ~[slick-hikaricp_2.11-3.1.0.jar:na]
    at play.api.db.slick.evolutions.internal.DBApiAdapter$DatabaseAdapter.getConnection(DBApiAdapter.scala:57) ~[play-slick-evolutions_2.11-1.1.1.jar:1.1.1]
    at play.api.db.slick.evolutions.internal.DBApiAdapter$DatabaseAdapter.getConnection(DBApiAdapter.scala:60) ~[play-slick-evolutions_2.11-1.1.1.jar:1.1.1]
    at play.api.db.evolutions.DatabaseEvolutions.databaseEvolutions(EvolutionsApi.scala:119) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.DatabaseEvolutions.scripts(EvolutionsApi.scala:97) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.DatabaseEvolutions.scripts(EvolutionsApi.scala:112) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.DefaultEvolutionsApi.scripts(EvolutionsApi.scala:77) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.ApplicationEvolutions$$anonfun$play$api$db$evolutions$ApplicationEvolutions$$runEvolutions.apply$mcV$sp(ApplicationEvolutions.scala:50) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.ApplicationEvolutions.withLock(ApplicationEvolutions.scala:98) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.ApplicationEvolutions.play$api$db$evolutions$ApplicationEvolutions$$runEvolutions(ApplicationEvolutions.scala:49) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.ApplicationEvolutions$$anonfun$start.apply(ApplicationEvolutions.scala:42) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.ApplicationEvolutions$$anonfun$start.apply(ApplicationEvolutions.scala:42) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at scala.collection.immutable.Stream.foreach(Stream.scala:594) ~[scala-library-2.11.7.jar:na]
    at play.api.db.evolutions.ApplicationEvolutions.start(ApplicationEvolutions.scala:42) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.ApplicationEvolutions.<init>(ApplicationEvolutions.scala:149) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.ApplicationEvolutionsProvider.get$lzycompute(EvolutionsModule.scala:53) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.ApplicationEvolutionsProvider.get(EvolutionsModule.scala:53) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at play.api.db.evolutions.ApplicationEvolutionsProvider.get(EvolutionsModule.scala:44) ~[play-jdbc-evolutions_2.11-2.4.0.jar:2.4.0]
    at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:81) ~[guice-4.0.jar:na]
    at com.google.inject.internal.BoundProviderFactory.provision(BoundProviderFactory.java:72) ~[guice-4.0.jar:na]
    at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61) ~[guice-4.0.jar:na]
    at com.google.inject.internal.BoundProviderFactory.get(BoundProviderFactory.java:62) ~[guice-4.0.jar:na]
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.call(ProviderToInternalFactoryAdapter.java:46) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103) ~[guice-4.0.jar:na]
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) ~[guice-4.0.jar:na]
    at com.google.inject.internal.SingletonScope.get(SingletonScope.java:145) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.call(InternalInjectorCreator.java:205) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.call(InternalInjectorCreator.java:199) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:199) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:180) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110) ~[guice-4.0.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:96) ~[guice-4.0.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:73) ~[guice-4.0.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:62) ~[guice-4.0.jar:na]
    at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:126) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:93) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$$anon$$anonfun$get$$anonfun$apply$$anonfun$$anonfun.apply(DevServerStart.scala:153) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$$anon$$anonfun$get$$anonfun$apply$$anonfun$$anonfun.apply(DevServerStart.scala:150) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$$anon$$anonfun$get$$anonfun$apply$$anonfun.apply(DevServerStart.scala:150) ~[play-server_2.11-2.4.3.jar:2.4.3]
    ... 15 common frames omitted
Caused by: java.lang.NullPointerException: null
    at slick.jdbc.DriverDataSource.getConnection(DriverDataSource.scala:98) ~[slick_2.11-3.1.0.jar:na]
    at com.zaxxer.hikari.pool.BaseHikariPool.addConnection(BaseHikariPool.java:438) ~[HikariCP-java6-2.3.7.jar:na]
    at com.zaxxer.hikari.pool.BaseHikariPool.run(BaseHikariPool.java:413) ~[HikariCP-java6-2.3.7.jar:na]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_66]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_66]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_66]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_66]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_66]

这是我的 build.sbt:

name := """et"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.7"

libraryDependencies ++= Seq(
    cache,
    ws,
    "com.typesafe.slick" %% "slick" % "3.1.0",
    "org.slf4j" % "slf4j-nop" % "1.6.4",
    "com.typesafe.play" %% "play-slick" % "1.1.1",
    "com.typesafe.play" %% "play-slick-evolutions" % "1.1.1",
    "org.postgresql" % "postgresql" % "9.4-1205-jdbc42"
)

resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"

routesGenerator := InjectedRoutesGenerator

和application.conf:

play.evolutions.db.default.enabled = true

slick.dbs.default.driver = "slick.driver.PostgresDriver$"
slick.dbs.default.db.driver = "org.postgresql.Driver"
slick.dbs.default.db.dataSourceClass = "slick.jdbc.DatabaseUrlDataSource"
slick.dbs.default.db.properties.driver = "org.postgresql.Driver"
slick.dbs.default.db.url = "jdbc:postgresql://localhost:5432/mydb"
slick.dbs.default.user = "postgres"
slick.dbs.default.password = "postgres"

根据文档 (https://www.playframework.com/documentation/2.4.x/PlaySlick),一切都应该没问题,所以这里可能出了什么问题?

更新: 我注意到一件重要的事情——我有一个单一的数据库演变,一旦我删除它——错误就消失了。不过我确实需要进化,所以问题仍然存在。

UPDATE2: 所以我在 github 上发现了一些相关问题,但没有解决方案: https://github.com/playframework/play-slick/issues/275 https://github.com/playframework/playframework/issues/4675

问题出在配置上,这是一个有效的示例:

slick.dbs.default.driver = "slick.driver.PostgresDriver$"
slick.dbs.default.db.driver = "org.postgresql.Driver"
slick.dbs.default.db.url = "jdbc:postgresql://localhost:5432/mydb"
slick.dbs.default.db.user = "postgres"
slick.dbs.default.db.password = "postgres"

请注意,如果您输入了错误的登录详细信息,它仍然会作为超时而不是身份验证错误或类似错误返回。

我在使用 Play 2.5.9 和 Slick 3.11 时遇到了这个问题。我通过添加 slick.dbs.default.db.properties.url:

解决了它
slick.dbs.default.db.url="jdbc:postgresql://<hostname>:<port>/<db>"
slick.dbs.default.db.properties.url="jdbc:postgresql://<hostname>:<port>/<db>"

增加超时对我有用。

slick.dbs.default.db.connectionTimeout = 5000