0

我发现Akka 登陆页面上提供的 Akka 远程处理的介绍性示例作为介绍有点难以理解,并且学习远程处理的来龙去脉所需的文档长度因介绍性目的而结构不正确。

下面是来自上述示例的代码,我想要求在一些公平的上下文中描述该代码的含义,同时涉及是否可以远程向任何参与者发送消息的问题,就好像它是本地的一样只需要仅仅改变配置。先前关于这最后一点的答案似乎与当前的 Akka 文档有些矛盾,而文档本身对这一点有些不确定。

// ------------------------------
// config on all machines
akka {
 actor {
   provider = akka.remote.RemoteActorRefProvider
   deployment {
     /greeter {
       remote = akka.tcp://MySystem@machine1:2552
     }
   }
 }
}

// ------------------------------
// define the greeting actor and the greeting message
case class Greeting(who: String) extends Serializable

class GreetingActor extends Actor with ActorLogging {
  def receive = {
    case Greeting(who) ⇒ log.info("Hello " + who)
  }
}

// ------------------------------
// on machine 1: empty system, target for deployment from machine 2
val system = ActorSystem("MySystem")

// ------------------------------
// on machine 2: Remote Deployment - deploying on machine1
val system = ActorSystem("MySystem")
val greeter = system.actorOf(Props[GreetingActor], name = "greeter")

// ------------------------------
// on machine 3: Remote Lookup (logical home of “greeter” is machine2, remote deployment is transparent)
val system = ActorSystem("MySystem")
val greeter = system.actorSelection("akka.tcp://MySystem@machine2:2552/user/greeter")
greeter ! Greeting("Sonny Rollins")

因此,对这个示例代码的介绍性解释也会非常有帮助。一个解释应该希望能够选择一个可以在单个 JVM 内以及跨 JVM 和服务器边界轻松扩展的参与者架构,而不是进入几天甚至更多的实验模式。

谢谢!

4

1 回答 1

3

从下到上解释您发布的示例可能最容易。最后,它显示了普通位置透明度,以获取我们不会硬编码位置字符串的演员参考。通过这个小的修改,我们得到:

// ------------------------------
// on machine 3: Remote Lookup (logical home of “greeter” is machine2, remote deployment is transparent)
val system = ActorSystem("MySystem")
val greeter = system.actorSelection(uri) // where uri is from config or some directory
greeter ! Greeting("Sonny Rollins")

如何从配置中查找演员的位置显示在 可以从配置中查找 akka 演员地址吗?它总结了使用演员的位置透明度。一旦通过 uri 从选择中获得 ActorRef,您就不需要知道它是本地演员还是远程演员,您只需向它发送消息即可。

将示例向上移动到它说的位置:

// ------------------------------
// on machine 2: Remote Deployment - deploying on machine1
val system = ActorSystem("MySystem")
val greeter = system.actorOf(Props[GreetingActor], name = "greeter")

这是为了展示部署参与者的本地透明度。这actorOf是工厂实例化而不是查找,因此它是部署。name 属性将其部署到“/user/greeter”的 uri 路径。如果您有单个 jvm 配置(例如空配置)并在单个进程中运行它,您将获得一个本地参与者部署到单个 jvm 中。然而,示例评论说它在 machine2 上运行并部署到 machine1 中;这是因为每个 jvm 的配置都在文件的后面:

akka {
 actor {
   provider = akka.remote.RemoteActorRefProvider
   deployment {
     /greeter {
       remote = akka.tcp://MySystem@machine1:2552
     }
   }
 }
}

也就是说,用户空间“/user/greeter”将使用 RemoteActorRefProvider 远程部署到 machine1 上的 Actor 系统 MySystem 上。如果您取出该配置,则要部署的示例代码不会远程部署,而是本地部署。如果它是本地部署,您可以使用本地路径查找它,而无需完整的 uri 指向它实际部署到的系统。无论是本地部署还是远程部署,您都会收到一个 ActorRef 并向其发送消息。

将文件向上移动一些:

// ------------------------------
// on machine 1: empty system, target for deployment from machine 2
val system = ActorSystem("MySystem")

这只是告诉您,如果您有配置将位置“greeter”的actor远程部署到machine1上的“MySystem”中,那么您应该在machine1上启动一个名称与配置匹配的actor系统。如果不是,您将在尝试从其他机器部署或解析“问候语”时遇到连接或查找错误。

最后,actor 本身是位置透明的,因为它与位置无关,如下所示:

// ------------------------------
// define the greeting actor and the greeting message
case class Greeting(who: String) extends Serializable

class GreetingActor extends Actor with ActorLogging {
  def receive = {
    case Greeting(who) ⇒ log.info("Hello " + who)
  }
}

所以那个actor不知道它是本地actor还是远程actor,还是使用akka Testkit在单元测试中运行。实际上,部署在所有机器中的配置文件正在修改参与者系统的工厂行为,以将其部署到“greeter”位置到一台机器中。

于 2014-10-19T12:11:18.140 回答