Akka.net: доступ к удаленным субъектам в кластере

В кластерной среде у меня есть начальный узел, узел1 и узел2.

Из node1 я хочу отправить сообщение актеру, который был создан на node2. Локальный путь к этому узлу на node2 — akka:MyAkkaSystem/user/AnActor.

Теперь я хочу отправить сообщение от Актера из node1 этому конкретному актеру, используя ActorSelection следующим образом:

var actorSystem = ActorSystem.Create("MyTestSystem");
var c = actorSystem.ActorSelection("/user/ConsoleReceiver");
c.Tell("Hello World");

На node2 актор был создан так:

var actorSystem = ActorSystem.Create("MyTestSystem");
            var r = actorSystem.ActorOf(Props.Create<MessageReceiver>(), "ConsoleReceiver");
            Console.WriteLine(r.Path);
            Console.ReadLine();
            actorSystem.Terminate().Wait();

К сожалению, это не сработает, так как попытка заканчивается мертвыми буквами.

Конфигурация HOCON на node2 выглядит так:

akka {
    actor {
      provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"                  
      deployment {                  
      }              
    }

    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
      }
    }            

    cluster {
      #will inject this node as a self-seed node at run-time
      seed-nodes = ["akka.tcp://[email protected]:4053"] #manually populate other seed nodes here, i.e. "akka.tcp://[email protected]:4053", "akka.tcp://[email protected]:4044"
      roles = [crawler]
    }
  }

В качестве начального узла я использую маяк. С точки зрения подключения вроде все работает. Семя было найдено, и каждый полученный узел получил приветственное сообщение.

Я думал, что у меня есть прозрачность местоположения в кластере и я могу получить доступ к удаленным ресурсам, как если бы они были локальными.


person Oliver Vogel    schedule 25.02.2016    source источник


Ответы (1)


Я думал, что у меня есть прозрачность местоположения в кластере и я могу получить доступ к удаленным ресурсам, как если бы они были локальными.

Это не так просто. Рассмотрим следующий сценарий: Что делать, если вы создали действующее лицо на обоих узлах по одному и тому же пути. Если вы попытаетесь использовать относительный путь, не показывая, какой узел вы имеете в виду, какой из акторов должен получить сообщение?.

Используя базовые возможности кластера, вы можете легко выбрать узел, используя Context.ActorSelection(_cluster.ReadView.Members.Single(m => /* which node you want to choose */).Address + "/user/ConsoleReceiver");. Расширение кластера дает вам данные для чтения с информацией обо всех членах, видимых из текущего узла.

Существует множество способов отправить сообщение другому субъекту, не зная, на каком узле оно находится.

Первый подход заключается в использовании функции Akka.Cluster.Tools кластера singleton, которая позволяет создать не более одного экземпляра. актора, присутствующего в кластере. В случае сбоя узла он будет мигрировать на другой узел. Имейте в виду, что это решение не следует использовать, если вы хотите, чтобы многие актеры работали таким образом. Это больше для отдельных, особых актеров.

Второй подход заключается в использовании Akka.Cluster.Tools функции Distributed Pub/Sub для трансляции событий в масштабе всего кластера. среди субъектов в кластере подписались на определенную тему, не беспокоясь об их фактическом местонахождении. Это хороший выбор для сценариев широковещательной рассылки сообщений.

Последний подход заключается в использовании функции Akka.Cluster.Sharding, которая автоматически управляет жизненным циклом акторов. не нужно явно создавать субъектов — он также может направлять им сообщения из любого места в кластере и при необходимости может перебалансировать их между многими узлами кластера.

person Bartosz Sypytkowski    schedule 25.02.2016
comment
Ну, что ж, спасибо. Однако я думал, что узлы связаны друг с другом из-за сплетен Кластера. Итак, если узлы подключены, почему я не могу обращаться к ним напрямую? - person Oliver Vogel; 09.03.2016
comment
Что вы имеете в виду под прямым текстом? В первом абзаце я описал прямой доступ к актору на узле. - person Bartosz Sypytkowski; 10.03.2016
comment
Что ж, казалось, что вам нужно пройти долгий путь, чтобы добраться до удаленных акторов, запрашивая кластер, синглтон, сегментирование, публикацию/подписку и т. д. (что является отличными функциями). Но поскольку узлы уже подключены, не проще ли сказать: ActorSelection([роль узла]/[путь к актеру]) или сделать его прозрачным с помощью изящной магии HOCON на стороне клиента? - person Oliver Vogel; 10.03.2016
comment
Вы можете легко извлечь эту информацию из cluster.ReadView.Members - они уже содержат информацию об адресах и ролях каждого узла кластера. Или вы могли бы, вероятно, использовать для этого маршрутизаторы группы кластера. - person Bartosz Sypytkowski; 10.03.2016
comment
Вот и все: групповые маршрутизаторы. Спасибо. - person Oliver Vogel; 10.03.2016
comment
Для тех, кто недавно посещал эту страницу, ReadView был амортизирован из объекта кластера, теперь вы можете использовать состояние для доступа к списку членов. - person GreatSamps; 16.05.2017