在Phantom DSL和Play中自动重试不可用的主机(NoHostAvailableException)! 2

时间:2016-10-19 10:06:16

标签: scala cassandra playframework-2.0 phantom-dsl

我目前正致力于将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)

我的游戏! controller使用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容器完全初始化时工作正常,这看起来并不理想,我希望在连接失败后重试它

1 个答案:

答案 0 :(得分: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