gpt4 book ai didi

Akka 2.1 远程 : sharing actor across systems

转载 作者:行者123 更新时间:2023-12-02 03:49:52 24 4
gpt4 key购买 nike

我正在学习 Akka 2.1 中的远程 actor,我尝试调整 counter example provided by Typesafe .我从控制台实现了一个 quick'n'dirty UI 来发送报价。并退出询问(并显示结果)当前计数。

这个想法是启动一个主节点来运行 Counter actor 和一些客户端节点,这些节点将通过远程处理向它发送消息。但是我想通过配置和对代码的最小更改来实现这一点。因此,通过更改配置,可以使用本地参与者。

我找到了 this blog entry关于类似的问题,即使有许多实例在运行,所有 API 调用都必须通过一个参与者。

我写了类似的配置,但我无法让它工作。我当前的代码确实使用了远程处理,但它在主节点上为每个新节点创建了一个新的 actor,如果不显式地给它路径(并且违反配置点),我无法让它连接到现有的 actor。然而,这不是我想要的,因为状态不能以这种方式在 JVM 之间共享。

完整的可运行代码可用through a git repo

这是我的配置文件

akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
deployment {
/counter {
remote = "akka://ticker@127.0.0.1:2552"
}
}
}
remote {
transport = "akka.remote.netty.NettyRemoteTransport"
log-sent-messages = on
netty {
hostname = "127.0.0.1"
}
}
}

和完整的来源

import akka.actor._
import akka.pattern.ask
import scala.concurrent.duration._
import akka.util.Timeout
import scala.util._

case object Tick
case object Get

class Counter extends Actor {
var count = 0

val id = math.random.toString.substring(2)
println(s"\nmy name is $id\ni'm at ${self.path}\n")
def log(s: String) = println(s"$id: $s")

def receive = {
case Tick =>
count += 1
log(s"got a tick, now at $count")
case Get =>
sender ! count
log(s"asked for count, replied with $count")
}
}

object AkkaProjectInScala extends App {
val system = ActorSystem("ticker")
implicit val ec = system.dispatcher

val counter = system.actorOf(Props[Counter], "counter")

def step {
print("tick or quit? ")
readLine() match {
case "tick" => counter ! Tick
case "quit" => return
case _ =>
}
step
}
step

implicit val timeout = Timeout(5.seconds)

val f = counter ? Get
f onComplete {
case Failure(e) => throw e
case Success(count) => println("Count is " + count)
}

system.shutdown()
}

我使用 sbt run 并在另一个窗口中使用 sbt run -Dakka.remote.netty.port=0 来运行它。

最佳答案

我发现我可以使用某种模式。 Akka remote 仅允许在远程系统上部署(无法通过配置找到使其在远程系统上查找的方法..我在这里弄错了吗?)。

所以我可以部署一个“侦察兵”来传回 ActorRef。可运行代码在分支“scout-hack”下的原始仓库中可用。因为这感觉就像一个黑客。我仍然会欣赏基于配置的解决方案。

Actor

case object Fetch

class Scout extends Actor{
def receive = {
case Fetch => sender ! AkkaProjectInScala._counter
}
}

Counter actor 的创建现在变得懒惰了

lazy val _counter = system.actorOf(Props[Counter], "counter")

所以只在master上执行(由端口决定),可以这样取

val counter: ActorRef = {
val scout = system.actorOf(Props[Scout], "scout")
val ref = Await.result(scout ? Fetch, timeout.duration) match {
case r: ActorRef => r
}
scout ! PoisonPill
ref
}

和完整的配置

akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
deployment {
/scout {
remote = "akka://ticker@127.0.0.1:2552"
}
}
}
remote {
transport = "akka.remote.netty.NettyRemoteTransport"
log-sent-messages = on
netty {
hostname = "127.0.0.1"
}
}
}

编辑:我还找到了一种简洁的方法:检查“counterPath”的配置,如果存在 actorFor(path) 则创建 actor。很好,你可以在运行时注入(inject) master,代码比使用“侦察兵”要干净得多,但它仍然需要决定天气来查找或创建 Actor 。我想这是无法避免的。

关于Akka 2.1 远程 : sharing actor across systems,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14799276/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com