Не удалось отправить сообщение удаленному участнику akka

0

Вопрос

Я новичок в удаленном управлении akka и пытаюсь просто отправить сообщение удаленному исполнителю и получить ответ в ответ. У меня есть 2 системы субъектов на локальном хосте - разные порты: мастерсистема и рабочая система. Я создал актера в рабочей системе и попытался отправить сообщение на его удаленный адрес. Но я продолжаю получать сообщение "обнаружены мертвые письма"! Буду признателен за любую помощь. Спасибо!

MainMaster.java

package pi_swarm_approx;

import akka.actor.ActorRef;
import akka.actor.ActorSelection;
import akka.actor.ActorSystem;
import akka.actor.UntypedActor;
import com.typesafe.config.ConfigFactory;

public class MainMaster extends UntypedActor{
    ActorSystem system;
    ActorRef actor;
    ActorSelection remoteActor;
    
    public MainMaster() {
        system = ActorSystem.create("MasterSystem", ConfigFactory.load("master"));
        System.out.println("MasterSystem created");
        MainWorker mw = new MainWorker();
        System.out.println("MainWorker obj created");
        remoteActor = mw.system.actorSelection("akka://WorkerSystem@localhost:2552/user/workerActor");
        
        System.out.println("Remote actor created");    
        remoteActor.tell("hello", getSelf());
        System.out.println("Message sent to remote actor");
    }
    
    public void onReceive(Object msg) {
        if (msg != null) {
            System.out.println("Got it back");
        }
         else {
            unhandled(msg);
            getContext().stop(getSelf());
         }
    }
}

MainWorker.java

package pi_swarm_approx;

import akka.actor.ActorSystem;
import akka.actor.ActorRef;
import com.typesafe.config.ConfigFactory;
import akka.actor.Props;

public class MainWorker {
    ActorSystem system;
    ActorRef actor;
    public MainWorker() {
        this.system = ActorSystem.create("WorkerSystem", ConfigFactory.load("worker"));
        actor = system.actorOf(Props.create(Worker.class), "workerActor");
    }
}

Worker.java

package pi_swarm_approx;

import akka.actor.UntypedActor;

public class Worker extends UntypedActor {  
    public void onReceive(Object msg) {
        System.out.println("Worker actor got message");
        if (msg != null) {
            getSender().tell("Request processed", getSelf());
        }
         else {
            unhandled(msg);
         }
        getContext().stop(getSelf());
    }
}

мастер.конф

akka {
  actor {
    provider = "cluster"
  }
  remote {
  transport = ["akka.remote.netty.tcp"]
    netty.tcp {
      hostname = "localhost"
      port = 2551
    }
  }
  
  clustering {
    cluster.name = "MasterSystem"
    role = "master"
  }
 }

рабочий.конф

akka {
  actor {
    provider = "cluster"
    deployment {
        /workerActor {
          remote = "akka.tcp://WorkerSystem@localhost:2552"
        }
  }
}

Выход

In main
MasterSystem created
MainWorker obj created
Remote actor created
Message sent to remote actor
[INFO] [11/22/2021 16:01:34.531] [WorkerSystem-akka.actor.default-dispatcher-5] [akka://WorkerSystem/deadLetters] Message [java.lang.String] from Actor[akka://Main/user/app#402333018] to Actor[akka://WorkerSystem/deadLetters] was not delivered. [1] dead letters encountered. If this is not an expected behavior, then [Actor[akka://WorkerSystem/deadLetters]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
<=========----> 75% EXECUTING [18s]
akka akka-remoting java
2021-11-22 10:59:44
1

Лучший ответ

1

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

Во-первых, вы используете устаревшую версию akka.actor.UntypedActor. Это было признано устаревшим в 2.4.0. Если вы используете maven соответствующим образом измените зависимости. Код был скомпилирован и запущен на java 11.

сборка.sbt

libraryDependencies ++=
  Seq(
    "com.typesafe.akka" %% "akka-actor" % "2.6.17",
    "com.typesafe.akka" %% "akka-remote" % "2.6.17",
  )

Для provider Я использовал remote вместо cluster. Вы можете использовать cluster, но убедитесь, что вы добавили необходимые зависимости. Конфигурацию можно еще больше упростить, удалив повторения, но вы можете делать это по мере изучения.

мастер.конф

akka {
  actor {
    provider = "remote"
  }
  remote {
    artery {
      enabled = on
      transport = tcp
      canonical {
        hostname = "127.0.0.1"
        port = 2552
      }
    }
  }
}

рабочий.конф

akka {
  actor {
    provider = "remote"
  }
  remote {
    artery {
      enabled = on
      transport = tcp
      canonical {
        hostname = "127.0.0.1"
        port = 2551
      }
    }
  }
}

MainMaster.java

import akka.actor.AbstractActor;

public class MainMaster extends AbstractActor {
    @Override
    public Receive createReceive() {
        return receiveBuilder()
            .match(
                    String.class,
                    System.out::println)
            .matchAny(o -> System.out.println("received unknown message"))
            .build();
    }
}

Worker.java

public class Worker extends AbstractActor {

    @Override
    public Receive createReceive() {
        return receiveBuilder()
            .match(
                    String.class,
                    msg -> {
                        System.out.println(msg);
                        getSender().tell("Request processed", getSelf());
                    })
            .matchAny(o -> System.out.println("received unknown message"))
            .build();
    }
}

MainWorker.java

public class MainWorker {

    public static void main(String[] args) {
        ActorSystem system = ActorSystem.create("WorkerSystem", ConfigFactory.load("worker.conf"));
        ActorRef actor = system.actorOf(Props.create(Worker.class), "workerActor");
        System.out.println("worker started");
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        System.out.println("In main");
        ActorSystem system = ActorSystem.create("MasterSystem", ConfigFactory.load("master.conf"));
        ActorRef master = system.actorOf(Props.create(MainMaster.class), "master");

        ActorSelection remoteActor = system.actorSelection("akka://[email protected]:2551/user/workerActor");
        remoteActor.tell("Hello Worker", master);
    }
}
2021-11-22 17:59:51

Спасибо за ответ. Однако один вопрос: когда создается рабочая система? Я не вижу, чтобы где-либо создавался объект MainWorker.
Deepika Vemuri

Будучи удаленными системами, вы должны учитывать MainWorker и Main как отдельные приложения и запускаются как таковые. В данном конкретном случае выполните MainWorker сначала за ним последовали Main так что пример Worker инициализируется и доступен для поиска с Main.
Johny T Koshy

К сожалению, я все еще получаю сообщение "обнаружены мертвые письма". Я попытался создать workerActor в Main.java и ActorSelection remoteActor = system1.actorSelection("akka://WorkerSystem/user/workerActor"); работает. Но, ActorSelection remoteActor = system.actorSelection("akka://[email protected]:2551/user/workerActor"); не.
Deepika Vemuri

Если MainWorker еще не запущен, когда вы начинаете Main, вы получите это сообщение. Проверьте, так ли это.
Johny T Koshy

Кроме того, это ActorRef actor = system1.actorOf(Props.create(Worker.class), "workerActor"); System.out.println(actor.path().address().host()); не возвращает Ни одного.
Deepika Vemuri

Можете ли вы показать обновленную структуру файлов и файлы на github?
Johny T Koshy


worker.conf и master.conf помещаются под resources/configs. К ним можно получить доступ для ActorSystem создание с использованием ActorSystem.create("MasterSystem", ConfigFactory.load("master.conf"));. Поставьте conf файлы в resources папка, она должна работать
Johny T Koshy

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................