В вашем первом примере вы используете маршрутизатор, который будет отправлять только один маршрут. Из документов, которые я прочитал, этот маршрутизатор будет использовать метрики, доступные из разных узлов, чтобы выбрать узел, который, по-видимому, находится под наименьшим принуждением, и отправить сообщение маршруту, который находится на этом узле. Я думаю, что поведение, которое вы видите для этой настройки, ожидаемо.
Что касается вашего второго примера, я ничего не нашел в документах об использовании BraodcastRouter
в кластерной среде, поэтому я не уверен, что этот подход поддерживается. Сказав это, я предполагаю, что создание BraodcastRouter
с пустым списком маршрутов (Nil
) является причиной поведения, которое вы видите. Я думаю, если вы измените это на BroadcastRouter(100)
, вы можете увидеть другое поведение. Но опять же, я не думаю (из-за отсутствия примера в документации), что использование BroadcastRouter
поддерживается (и я могу ошибаться).
Можете ли вы немного подробнее объяснить свой вариант использования, чтобы я мог понять, зачем вам нужен маршрутизатор широковещательного типа для вашего кластера?
Изменить
FWIW, у меня все работает со следующим кодом. Во-первых, конфиг:
akka {
actor {
provider = "akka.cluster.ClusterActorRefProvider"
}
remote {
transport = "akka.remote.netty.NettyRemoteTransport"
log-remote-lifecycle-events = off
netty {
hostname = "127.0.0.1"
port = 0
}
}
cluster {
min-nr-of-members = 2
seed-nodes = [
"akka://[email protected]:2551",
"akka://[email protected]:2552"]
auto-down = on
}
}
Затем я запустил два узла (один на 2551, другой на 2552), используя следующий код:
object ClusterNode {
def main(args: Array[String]): Unit = {
// Override the configuration of the port
// when specified as program argument
if (args.nonEmpty) System.setProperty("akka.remote.netty.port", args(0))
// Create an Akka system
val system = ActorSystem("ClusterSystem")
val clusterListener = system.actorOf(Props(new Actor with ActorLogging {
def receive = {
case state: CurrentClusterState =>
log.info("Current members: {}", state.members)
case MemberJoined(member) =>
log.info("Member joined: {}", member)
case MemberUp(member) =>
log.info("Member is Up: {}", member)
case UnreachableMember(member) =>
log.info("Member detected as unreachable: {}", member)
case _: ClusterDomainEvent => // ignore
}
}), name = "clusterListener")
Cluster(system).subscribe(clusterListener, classOf[ClusterDomainEvent])
}
}
class FooActor extends Actor{
override def preStart = {
println("Foo actor started on path: " + context.self.path)
}
def receive = {
case msg => println(context.self.path + " received message: " + msg)
}
}
Затем я запустил третий «узел», мой клиентский узел, используя следующий код:
object ClusterClient {
def main(args: Array[String]) {
val system = ActorSystem("ClusterSystem")
Cluster(system) registerOnMemberUp{
val router = system.actorOf(Props[FooActor].withRouter(
ClusterRouterConfig(AdaptiveLoadBalancingRouter(HeapMetricsSelector),
ClusterRouterSettings(
totalInstances = 20, maxInstancesPerNode = 10,
allowLocalRoutees = false))),
name = "fooRouter")
router ! Broadcast("bar")
}
}
}
Когда сообщение было отправлено, я увидел, что оно было получено на обеих виртуальных машинах узла сервера, по 10 участников на каждую виртуальную машину.
Отличие моего роутера от вашего в том, что я не указал локальные маршруты и заменил routeesPath
на maxInstancesPerNode
. Надеюсь, это поможет.
person
cmbaxter
schedule
21.05.2013