Я хочу создать простой одноэлементный кластер и отправить сообщение с удаленного узла
Здесь я создал синглтон актера. Мастер и начальный узел одинаковы. Из другого проекта я пытаюсь добавить в кластер и хочу отправить сообщение. Я могу присоединиться к кластеру, но не могу отправить сообщение.
Мой мастер и начальный узел:
package Demo
import akka.actor._
import akka.cluster.singleton.{ClusterSingletonManager, ClusterSingletonManagerSettings, ClusterSingletonProxy, ClusterSingletonProxySettings}
import com.typesafe.config.ConfigFactory
import scala.concurrent.duration._
object MainObject1 extends App{
DemoMain1.start(8888)
}
object DemoMain1 {
val role = "test"
val singletonname = "Ruuner"
val mastername = "Master"
def start(port: Int): ActorSystem = {
val conf = ConfigFactory.parseString(
s"""
|akka.actor.provider = "akka.cluster.ClusterActorRefProvider"
|
|akka.remote.netty.tcp.port = $port
|akka.remote.netty.tcp.hostname = 127.0.0.1
|akka.cluster.roles = ["$role"]
|akka.cluster.seed-nodes = ["akka.tcp://DemoMain1@127.0.0.1:8888"]
""".stripMargin
)
val system = ActorSystem("DemoMain1", conf)
val settings = ClusterSingletonManagerSettings(system).withRole(role)
val manager = ClusterSingletonManager.props(Props[DemoMain1], PoisonPill, settings)
val actor=system.actorOf(manager, mastername)
system
}
class DemoMain1 extends Actor with Identification {
import context._
override def preStart(): Unit = {
println(s"Master is created with id $id in $system")
println(self.path.address.host)
system.scheduler.scheduleOnce(100.seconds, self, 'exit)
}
override def receive : Receive={
case 'exit => println("$id is exiting")
context stop self
//SupervisorStrategy.Restart
case msg => println(s"messasge from $system is $msg ")
sender() ! 'how
}
}
}
Другой узел, который пытается присоединиться к кластеру и отправить сообщение.
import akka.actor._
import akka.cluster.singleton.{ClusterSingletonProxy, ClusterSingletonProxySettings}
import com.typesafe.config.ConfigFactory
import scala.concurrent.duration._
object Ping extends App{
def ping: ActorSystem = {
val conf = ConfigFactory.parseString(
s"""
|akka.actor.provider = "akka.cluster.ClusterActorRefProvider"
|
|akka.remote.netty.tcp.port = 0
|akka.remote.netty.tcp.hostname = 127.0.0.1
|akka.cluster.roles = ["slave"]
|akka.cluster.seed-nodes = ["akka.tcp://DemoMain1@127.0.0.1:8888"]
|akka.cluster.auto-down-unreachable-after = 10s
""".stripMargin
)
val system = ActorSystem("DemoMain1", conf)
system.actorOf(Props[Ping])
system
}
class Ping extends Actor {
import context._
val path = "akka.tcp://DemoMain1@127.0.0.1:8888/DemoMain1/user/Master/actor"
val settings = ClusterSingletonProxySettings(system).withRole("slave")
val actor = context.actorOf(ClusterSingletonProxy.props(path, settings))
val pingInterval = 1.seconds
override def preStart(): Unit = {
system.scheduler.schedule(pingInterval, pingInterval) {
println(s"Locate Ping $system")
actor ! 'hi
}
}
override def receive: Receive = {
case msg => println(s"The message is $msg")
}
}
Ping.ping
}
Если я даю IP-адреса системы, то и сообщение не отправляется.
1 ответ
Похоже, role
в вашем ClusterSingletonProxySettings(system).withRole("slave")
настройки для вашего Ping
актер не соответствует твоему ClusterSingletonManagerSettings(system).withRole(role)
где role = "test"
,
ClusterSingletonProxy
должен присутствовать на всех узлах с указанным role
на котором настроен кластер, следовательно, его role
настройки должны совпадать ClusterSingletonManager
"S. Вот пример конфигурации.