阿卡遥控器中的死信(scala)

时间:2014-09-16 14:54:30

标签: scala akka remoting

当我尝试在我的localhost上使用远程akka actor运行一个简单的例子时,我遇到了死信。

这是远程项目的build.sbt文件。

name := "HelloRemote"

version := "1.0"

scalaVersion := "2.11.2"

resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-actor" % "2.3.6",
  "com.typesafe.akka" %% "akka-remote" % "2.3.6"
)

这是我的远程系统的application.conf文件。

akka {
  actor {
    provider = "akka.remote.RemoteActorRefProvider"
   }
   remote {
     enabled-transports = ["akka.remote.netty.tcp"]
     netty.tcp {
       hostname = "127.0.0.1"
       port = 5100
     }
   }
}

这是远程系统的HelloRemote.scala文件。

package remote

import akka.actor._

object HelloRemote extends App  {
  val system = ActorSystem("HelloRemoteSystem")
  val remoteActor = system.actorOf(Props[RemoteActor], name = "RemoteActor")
  remoteActor ! "The RemoteActor is alive"
}

class RemoteActor extends Actor {
  def receive = {
    case msg: String =>
        println(s"RemoteActor received message '$msg'")
        sender ! "Hello from the RemoteActor"
  }
}

对于我的本地系统,build.sbt文件如下所示。

name := "HelloLocal"

version := "1.0"

scalaVersion := "2.11.2"

resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-actor" % "2.3.6",
  "com.typesafe.akka" %% "akka-remote" % "2.3.6"
)

我本地系统的application.conf文件是

akka {
  actor {
    provider = "akka.remote.RemoteActorRefProvider"
  }
  remote {
    enabled-transports = ["akka.remote.netty.tcp"]
    netty.tcp {
      hostname = "127.0.0.1"
      port = 0
    }
  }
}

本地系统的HelloLocal.scala文件是

package local

import akka.actor._

object Local extends App {

  val system = ActorSystem("LocalSystem")
  val localActor = system.actorOf(Props[LocalActor], name = "LocalActor")  // the local actor
  localActor ! "START"                                                     // start the action

}

class LocalActor extends Actor {

  // create the remote actor
  val remote = context.actorSelection("akka.tcp://HelloRemoteSystem@127.0.0.1:5100/user/RemoteActor")
  var counter = 0

  def receive = {
    case "START" =>
        remote ! "Hello from the LocalActor"
    case msg: String =>
        println(s"LocalActor received message: '$msg'")
        if (counter < 5) {
            sender ! "Hello back to you"
            counter += 1
        }
  }
}

当我第一次运行HelloRemote.scala时The RemoteActor is alive按预期打印,然后我立即收到错误

[INFO] [09/16/2014 10:52:47.585] [HelloRemoteSystem-akka.actor.default-dispatche
r-4] [akka://HelloRemoteSystem/deadLetters] Message [java.lang.String] from Acto
r[akka://HelloRemoteSystem/user/RemoteActor#1051175275] to Actor[akka://HelloRem
oteSystem/deadLetters] was not delivered. [1] dead letters encountered. This log
ging can be turned off or adjusted with configuration settings 'akka.log-dead-le
tters' and 'akka.log-dead-letters-during-shutdown'.

当我运行本地系统HelloLocal.scala时,我收到类似的错误,然后没有任何反应。我在这里做错了吗?

3 个答案:

答案 0 :(得分:2)

当您从演员外部发送消息时,Akka会将死信邮箱作为发件人填写。当RemoteActorHelloRemote.scala回复时,它会回复死信邮箱,因为它收到的邮件是在演员外发送的。

目前,HelloRemote.scala甚至没有涉及远程处理,因为你只是部署了一个本地演员。

当你运行HelloLocal.scala时,我怀疑你的HelloRemote演员系统正在终止,因为没有任何东西可以保持主要运行。

答案 1 :(得分:1)

之前我遇到过同样的问题,我使用val config = ConfigFactory.parsingString("---Configuration---")而不是使用配置文件解决了这个问题。 希望它适合你。

答案 2 :(得分:0)

我有这个问题,然后做同样的例子。我错过的部分是将application.conf放在src / main / resources目录中。

如果它在启动服务器时位于正确的位置,您应该会看到这样的INFO消息:

[INFO] [03/02/2016 19:06:10.365] [main] [akka.remote.Remoting] Starting remoting
[INFO] [03/02/2016 19:06:10.497] [main] [akka.remote.Remoting] Remoting started; listening on addresses : akka.tcp://HelloRemoteSystem@127.0.0.1:5100]
[INFO] [03/02/2016 19:06:10.499] [main] [akka.remote.Remoting] Remoting now listens on addresses: [akka.tcp://HelloRemoteSystem@127.0.0.1:5100]

我所关注的blog post的目录结构:

HelloRemote/
|-- build.sbt
|-- src
    |-- main
    │   |-- java
    │   |-- resources
    │   │   +-- application.conf <--------------------------
    │   +-- scala
    │       +-- remote
    │           +-- HelloRemote.scala
    +-- test
        |-- java
        |-- resources
        +-- scala

正如Ryan已经提到的那样,死信错误是String消息“RemoteActor is alive”的副作用,因为它不是一个actor,因此它无法接收消息“来自RemoteActor的Hello”。这是示例中的一个小错误,但不会导致远程和本地参与者无法相互交谈。