Может ли клиент кластера Akka отправлять сообщения узлам кластера, не входящим в начальные контакты?

Используя Akka 2.3.14, пытаюсь создать Akka-кластер из различных сервисов. До сих пор у меня были все мои «службы» в одном артефакте, который был кластеризован на нескольких узлах, но теперь я пытаюсь разбить этот артефакт на несколько служб, которые все существуют в одном кластере.

Поэтому, разбивая это на части, мы разработали его так, чтобы любой узел в кластере сначала пытался подключиться к начальным узлам. Если начального узла нет, он будет искать, является ли он кандидатом для запуска как начальный узел (если он находится на том же хосте, на котором может находиться начальный узел), и в этом случае он захватит порт открытого начального узла. и стать начальным узлом. Таким образом, в этом смысле любая служба в кластере может стать начальным узлом.

По крайней мере, такова была идея. Наш API в этой системе, работающий как отдельная служба, реализует ClusterClient в этой системе. Начальные контакты устанавливаются такими же, как начальные узлы. Проблема в том, что единственные актеры-регистраторы, которым я могу отправить сообщение через ClusterClient, - это акторы на начальных узлах.

Вот пример, если это поможет. Скажем, у меня есть String Service и Double Service, и регистратор для каждой службы - StringActor и DoubleActor соответственно. Теперь предположим, что у меня есть клиентская служба, которая отправляет StringMessages и DoubleMessages в StringActor и DoubleActor.

Итак, для простоты предположим, что у меня есть два узла, server1 и server2, тогда:

seed-nodes = ["akka.tcp://system@server1:2773", "akka.tcp://system@server2:2773"]

Мой ClusterClient будет инициализирован следующим образом:

system.actorOf(
    ClusterClient.props(
        Set(
            system.actorSelection("akka.tcp://system@server1:2773/user/receptionist"),
            system.actorSelection("akka.tcp://system@server2:2773/user/receptionist")
        )
    ),     
    "clusterClient"
)

Вот сценарии, которые со мной происходят:

  1. Если StringServices запускается сначала на обоих серверах, то DoubleMessages из клиентской службы просто исчезают в эфире.
  2. Если DoubleServices сначала запускается на обоих серверах, сообщения StringMessages из клиентской службы просто исчезают в эфире.
  3. Если StringService запускается сначала на serverX, а DoubleService запускается первым на serverY, тогда все StringMessages будут отправлены на serverX, а все DoubleMessages будут отправлены на serverY, что не так плохо, как в приведенном выше случае, но это означает, что на самом деле это не так. масштабирование.

Это не то, чего я ожидал, возможно, это просто дефект в моем коде, поэтому я хотел бы знать, является ли это ожидаемым поведением или нет. А если нет, то есть ли еще одна концепция Akka, которая могла бы мне в этом помочь?

Возможно, я мог бы просто сделать один тип службы своей точкой входа, например RoutingService, который мог бы принимать StringMessages или DoubleMessages, а затем отправить его в нужную службу. Но если клиентская служба может отправлять сообщения только экземплярам RoutingService, которые находятся в начальных контактах, тогда я не могу динамически масштабировать RoutingService, потому что независимо от того, сколько узлов я добавляю, клиентская служба может отправлять только начальным контактам.

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


person rhamilton    schedule 04.03.2016    source источник


Ответы (1)


Это то, что я обнаружил после дополнительных действий по устранению неполадок, на случай, если это поможет кому-то еще:

ClusterClient попытается подключиться к начальным контактам по порядку, а затем отправит сообщения только через это соединение. Если вы развертываете разные службы на каждом узле, у вас будут проблемы, поскольку сообщения, отправленные из ClusterClient, будут отправляться только на узел, к которому он подключается. Таким образом, вы можете думать о ClusterClient как о легитимном клиенте, он будет подключаться к URL-адресу, который вы ему даете, а затем продолжит связываться с сервером через этот URL-адрес.

Читая пример Distributed Workers, я понял, что мой Frontend или в этом случае моя служба маршрутизации должна фактически быть частью кластера, а не действовать как клиент. Вместо этого я использовал метод DistributedPubSub.

person rhamilton    schedule 15.03.2016
comment
Если вы подписываетесь на посредника со своими работниками, и ваша первоначальная точка контакта - это супервизор, содержащий посредника pub / sub, да, вы определенно можете подключиться к разным узлам в кластере. На этом этапе ваши IPOC работают больше как семенные узлы. - person Andrew Scott Evans; 05.07.2017