我正在用Akka.Cluster创建一个有三个节点A、B和C的示例,其中A是灯塔。到目前为止,从日志中看,当没有参与者或参与者是本地的(用spawn和spawnOpt创建)时,集群可以正常工作。我想从B中创建一个演员,然后从C中获得它。
使用
let _ = spawne system "r-actor" <@ actorOf (fun msg -> printfn "Received: %s" msg) @> []我得到了
2016-08-31 01:59:00.1185|INFO|Akka.Actor.EmptyLocalActorRef|Message String from akka://calculatorSystem/deadLetters to akka://calculatorSystem/user/r-actor was not delivered. 1 dead letters encountered.
使用
let r = FromConfig.Instance :> RouterConfig |> SpawnOption.Router
let _ = spawne system "r-actor" <@ actorOf (fun msg -> printfn "Received: %s" msg) @> [r]抛出异常
Akka.Configuration.ConfigurationException类型的未处理异常发生在Akka.dll中 附加信息:Configuration problem while creating [akka://calculatorSystem/user/r-actor] with router dispatcher [akka.actor.default-dispatcher] and mailbox and routee dispatcher [akka.actor.default-dispatcher] and mailbox [].
Node C上的测试函数是
let rec calculate content =
printfn "Processing %s" content
let actor = select "/user/r-actor" system
actor <! content
let text = Console.ReadLine()
if text <> "quit" then
calculate text
calculate "sample1"HOCON (节点B)
akka {
actor {
provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
serializers {
wire = "Akka.Serialization.WireSerializer, Akka.Serialization.Wire"
}
serialization-bindings {
"System.Object" = wire
}
deployment {
/user/add {
router = round-robin-pool
nr-of-instances = 10
cluster {
enabled = on
max-nr-of-instances-per-node = 10
allow-local-routees = off
}
}
/user/r-actor {
router = round-robin-pool
nr-of-instances = 10
cluster {
enabled = on
max-nr-of-instances-per-node = 10
allow-local-routees = off
}
}
}
}
remote {
log-remote-lifecycle-events = DEBUG
log-received-messages = on
helios.tcp {
transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
applied-adapters = []
transport-protocol = tcp
hostname = "127.0.0.1"
port = 0
}
}
loggers = ["Akka.Logger.NLog.NLogLogger,Akka.Logger.NLog"]
cluster {
seed-nodes = [
"akka.tcp://calculatorSystem@127.0.0.1:7001"
]
roles = ["add-service"]
auto-down-unreachable-after = 10s
}
}如何创建一个可以由集群中的另一个节点调用的参与者?
发布于 2016-08-31 08:21:07
定义路由器配置时,不要使用/user前缀-它是自动添加的。
另外,如果您想选择驻留在另一个节点上的参与者,您需要使用完整的参与者路径(带有节点地址)--这是因为事实上,可能有不同的参与者生活在不同的节点上,具有相同的路径。你必须精确。
通常,在编译时,您不会知道节点的地址。提取它的方法有两种:
1.从群集状态获取地址
这比较容易,但您正在失去加入/离开节点的反应能力。你每次都要检查它,这很慢。本例使用ActorSelection.ResolveOne检索实际的IActorRef实例。
async {
let members = Cluster.Get(system).State.Members
let actorRefs =
members
|> Seq.filter (fun m -> m.Roles.Contains("expected")) // use roles to filter out nodes that shouldn't be checked
|> Seq.map (fun m ->
let selection = select (m.Address.ToString() + "user/r-actor") system
let actorRef = selection.ResolveOne(timeout) |> Async.AwaitTask)
|> Async.Parallel }2.订阅群集事件并对连接/离开节点作出反应
在这里,您可以在节点加入/离开时对它们作出反应。它还使用Identify/ActorIdentity来接收实际的IActorRef,这是更快的选项。
let aref =
spawn system "listener"
<| fun mailbox ->
let cluster = Cluster.Get (mailbox.Context.System)
cluster.Subscribe (mailbox.Self, [| typeof<ClusterEvent.IMemberEvent> |])
mailbox.Defer <| fun () -> cluster.Unsubscribe (mailbox.Self)
let rec loop () =
actor {
let! (msg: obj) = mailbox.Receive ()
match msg with
| :? ClusterEvent.MemberUp as up ->
// new node joined the cluster
let selection = select (up.Member.Address.ToString() + "user/r-actor") mailbox
selection <! Identify(null) // request actor under selection to identify itself
| :? ActorIdentity as id when id.Subject <> null ->
// actor has identified itself
id.Subject <! "hello"
| :? ClusterEvent.MemberRemoved as rem ->
// node leaved the cluster, invalidate all actors from that node
| _ -> ()
return! loop () }
loop ()如果有疑问,我编写了一个关于从博客帖子创建Akka.NET集群的F#。也许你会发现它很有用。
https://stackoverflow.com/questions/39239608
复制相似问题