启动没有 DB 的 Java/Play2.5 REST API
Posted
技术标签:
【中文标题】启动没有 DB 的 Java/Play2.5 REST API【英文标题】:Start Java/Play2.5 REST API without DB 【发布时间】:2017-05-15 12:17:36 【问题描述】:我想开始我的 Java/Play!即使无法访问数据库也可以提供服务。到目前为止,如果数据库不可用,服务就会停止。是否可以在 Play 中尝试每隔一秒左右重新连接一次,而无需完全停止服务并在连接可用时立即重新连接到 db。
我们的 application.conf 目前看起来像这样:
play.evolutions.enabled=false
//play.db.pool=bonecp
db
default.driver=org.postgresql.Driver
default.url="jdbc:postgresql://postgresdb.postgres:5432/postcode"
default.username="<username>"
default.password="<strong-password>"
play.db
config = "db"
prototype.hikaricp =
connectionTimeout = 250 milliseconds
initializationFailFast = false
readOnly = true
ebean.default = ["models.*"]
目前我得到以下日志:
2017-05-15 13:26:54.525 [error] postcode-play: Connection error:
org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections
Ort: Datei: postinit.c, Routine: InitPostgres, Zeile: 779.
Server SQLState: 53300
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2412)
at org.postgresql.core.v3.QueryExecutorImpl.readStartupMessages(QueryExecutorImpl.java:2538)
at org.postgresql.core.v3.QueryExecutorImpl.<init>(QueryExecutorImpl.java:122)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:227)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:194)
at org.postgresql.Driver.makeConnection(Driver.java:431)
at org.postgresql.Driver.connect(Driver.java:247)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:95)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:101)
2017-05-15 13:26:54.626 [error] postcode-play: Connection error:
org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections
Ort: Datei: postinit.c, Routine: InitPostgres, Zeile: 779.
Server SQLState: 53300
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2412)
at org.postgresql.core.v3.QueryExecutorImpl.readStartupMessages(QueryExecutorImpl.java:2538)
at org.postgresql.core.v3.QueryExecutorImpl.<init>(QueryExecutorImpl.java:122)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:227)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:194)
at org.postgresql.Driver.makeConnection(Driver.java:431)
at org.postgresql.Driver.connect(Driver.java:247)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:95)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:101)
.
.
.
表明服务器并没有完全停止,而是根据需要多次尝试连接到 db。但如果数据库可用,则会写入以下日志:
2017-05-15 14:08:43.748 [error] postcode-play:
! @7430ed7gf - Internal server error, for (GET) [/?postcode=88682&country=DE] ->
play.api.Configuration$$anon$1: Configuration error[Cannot connect to database [default]]
at play.api.Configuration$.configError(Configuration.scala:155)
at play.api.Configuration.reportError(Configuration.scala:808)
at play.api.db.DefaultDBApi$$anonfun$connect$1.apply(DefaultDBApi.scala:48)
at play.api.db.DefaultDBApi$$anonfun$connect$1.apply(DefaultDBApi.scala:42)
at scala.collection.immutable.List.foreach(List.scala:392)
at play.api.db.DefaultDBApi.connect(DefaultDBApi.scala:42)
at play.api.db.DBApiProvider.get$lzycompute(DBModule.scala:72)
at play.api.db.DBApiProvider.get(DBModule.scala:62)
at play.api.db.DBApiProvider.get(DBModule.scala:58)
at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:81)
Caused by: java.sql.SQLTransientConnectionException: HikariPool-4 - Connection is not available, request timed out after 5001ms.
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:548)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:186)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:145)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:83)
at play.api.db.DefaultDatabase.getConnection(Databases.scala:142)
at play.api.db.DefaultDatabase.getConnection(Databases.scala:138)
at play.api.db.DefaultDBApi$$anonfun$connect$1.apply(DefaultDBApi.scala:44)
at play.api.db.DefaultDBApi$$anonfun$connect$1.apply(DefaultDBApi.scala:42)
at scala.collection.immutable.List.foreach(List.scala:392)
at play.api.db.DefaultDBApi.connect(DefaultDBApi.scala:42)
Caused by: org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:265)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:194)
at org.postgresql.Driver.makeConnection(Driver.java:431)
at org.postgresql.Driver.connect(Driver.java:247)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:95)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:101)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:341)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:193)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:430)
Caused by: java.net.ConnectException: Verbindungsaufbau abgelehnt (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.postgresql.core.PGStream.<init>(PGStream.java:62)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:144)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:194
)
服务器无法访问数据库,即使它现在可用。如果我重新启动服务器,将找到数据库并且可以使用该数据库,但数据库始终必须在启动时存在。我该如何解决这个问题,以便可以独立于数据库启动应用程序?
如果数据库在应用程序启动后变得不可用,那么在数据库再次可用后就没有问题了。它会自动重新连接。
非常感谢任何帮助!
【问题讨论】:
【参考方案1】:您似乎要为 Postgres 保留一些连接。这些连接必须关闭,否则 Postgres 将达到其max_connections
限制。
您可以increase max_connections
,但不建议这样做,因为如果设置得太高,Postgres 的性能会下降。此外,当您使用 HikariCP 时,查看HikariCP docs 并不是一个坏主意,尤其是idleTimeout
和minimumIdle
配置变量应该对您有所帮助。
如果上述方法不起作用,那么您必须准确确认与 Postgres 建立了多少连接。甚至可以检查您个人通过 SSH 或通过其他应用程序与 Postgres 进行的会话数量,而不仅仅是 Play Framework 连接的数量。
【讨论】:
以上是关于启动没有 DB 的 Java/Play2.5 REST API的主要内容,如果未能解决你的问题,请参考以下文章
Flyway、Spring Boot 和应用程序在没有数据库的情况下启动
有没有办法使用 quick.db 制作 discord.js 日志系统
ORA-04098 trigger 'DBBJ.DB_EV_ALTER_ST_METADATA' is invalid and failed re-validation
关于启动SpringBoot简单项目报错Error starting ApplicationContext. To display the conditions report re-run ..的问题