0

我目前正在将 Phantom DSL 集成到一个小型 Play 应用程序中。由于我们计划在 Docker 环境中运行应用程序,因此我在本地机器上使用 Docker Compose 来测试应用程序。

但是,当同时启动 Cassandra 实例和 Play 应用程序时,它无法连接或运行,因为 Play 应用程序在 Cassandra 之前可用。

我目前的连接器设置如下:

object Defaults {
  val connector = ContactPoint(sys.env("CASSANDRA_URL"), sys.env("CASSANDRA_PORT").toInt)
    .withClusterBuilder(_.withSocketOptions(
      new SocketOptions().setTcpNoDelay(true))
    ).keySpace("my_app")
}

像这样初始化数据库

class CassandraDB(val keyspace: KeySpaceDef) extends Database(keyspace) {
  object users extends ConcreteUsers with keyspace.Connector
  object articles extends ConcreteArticles with keyspace.Connector
  object comments extends ConcreteComments with keyspace.Connector
}


object CassandraDB extends CassandraDB(Defaults.connector)

还有我的游戏!控制器使用 CassandraDB 对象调用数据库

def index = Action.async {
  CassandraDB.users.getAll.map { users =>
    Ok(Json.toJson(users))
  }
}

第一次尝试连接到数据库会导致预期的 NoHostAvailableException

com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: localhost/127.0.0.1:9042)

之后的任何请求都将引发以下异常:

play.api.UnexpectedException: Unexpected exception[RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class models.CassandraDB$]

一旦发生这种情况,需要手动重新启动应用程序才能使其正常工作。

在等待 Cassandra 容器完全初始化工作正常时,这似乎并不理想,我希望在连接失败后重试

4

1 回答 1

0

好吧,我很清楚幻像和/或您的应用程序没有错吗?当容器正常工作时,两者都可以正常工作。

你试过订购你的作曲吗?

https://docs.docker.com/compose/startup-order/

编辑

根据我回答的 OP 问题,一个可能的解决方案是使用 Actor 方法,在这种方法中,您可以使用主管策略,以防数据库出现故障。

override def supervisorStrategy: SupervisorStrategy =
    OneForOneStrategy(maxNrOfRetries = 5) {
      case _: NoHostAvailableException => Restart
      case _: Exception => Stop
    }

因此,您可以拥有一个与您的数据库交互的 Actor,并且在尝试连接时,如果发生已知错误,您可以在主管上捕获它并决定要做什么。如果您决定重新启动,您可以使用 preRestart 方法重新连接。

override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
    log.warning(s"Restarting Actor due: {}", reason.getMessage)
    //do something here
  }

http://doc.akka.io/docs/akka/2.4.11/general/supervision.html http://doc.akka.io/docs/akka/2.4.11/scala/fault-tolerance.html

于 2016-10-19T21:21:47.637 回答