我正在学习Akka 2.1中的远程演员,我试图改编counter example provided by Typesafe . 我从控制台实现了一个快速的'n'脏UI来发送滴答声 . 并且询问(并显示结果)当前计数 .
我们的想法是启动一个主节点,它将运行Counter actor和一些客户端节点,它将通过远程处理向它发送消息 . 但是,我想通过配置和对代码的最小更改来实现这一点 . 因此,通过更改配置,可以使用本地actor .
我找到了this blog entry关于类似的问题,即使有很多实例正在运行,所有API调用都需要通过一个actor .
我写了类似的配置,但我不能让它工作 . 我当前的代码确实使用了远程处理,但它在主节点上为每个新节点创建了一个新的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
中运行它 .
2 回答
我发现我可以使用某种模式 . Akka远程只允许在远程系统上进行部署(无法通过配置找到让它在远程查找的方法......我错了吗?) .
所以我可以部署一个“侦察员”来传回ActorRef . 在“scout-hack”分支下的原始仓库中可用的可运行代码 . 因为这感觉就像一个黑客 . 我仍然会欣赏基于配置的解决方案 .
演员
反演员创造现在是懒惰的
因此它只在主服务器上执行(由端口确定),并且可以像这样获取
并完整配置
EDIT :我还发现了一种干净利落的方式:检查"counterPath" anf的配置如果存在,则为actor(路径),否则创建actor . 很好,你可以在运行时注入主人,代码比使用_2777178更干净但是它仍然需要决定天气查找或创建一个演员 . 我想这是无法避免的 .
我尝试了你的git项目,它实际上工作正常,除了编译错误,你必须使用
-Dakka.remote.netty.port=0
参数启动sbt会话到jvm,而不是run
的参数 .您还应该了解,您不必在两个进程中启动Counter actor . 在此示例中,它旨在从客户端创建并部署在服务器上(端口2552) . 您不必在服务器上启动它 . 对于此示例,在服务器上创建actor系统应该足够了 .