Akka Remote - 消息未送达(Java)

时间:2015-08-15 09:49:33

标签: java akka

尝试使用Akka进行并行计算,但在沟通演员时遇到问题。我有两个不同的角色(其名称是发送者和接收者),它们在两个不同的系统上工作,这两个系统在相同的IP地址(名称为SenderSystem和Receiver System)上的不同端口上工作。我想要做的是从发送者演员发送消息到接收者演员。但是在控制台上我看到了这样的消息

[INFO] [08/15/2015 12:36:51.645] [SenderSystem-akka.actor.default-dispatcher-4] [akka://SenderSystem/sender] Message [com.aliyesilkanat.akkadeneme.Messages$1] from Actor[akka://SenderSystem/deadLetters] to Actor[akka://SenderSystem/sender] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

这是 application.conf

akka {
  loglevel = "INFO"
  actor {
    provider = "akka.remote.RemoteActorRefProvider"
  }
  remote {
  untrusted-mode = off
    enabled-transports = ["akka.remote.netty.tcp"]
    netty.tcp {
      hostname = "127.0.0.1"
    } 

 }
}

sender.conf

include "application"
akka { 
    actor {
        deployment {
          /receiver {
            remote = "akka://ReceiverSystem@127.0.0.1:8091"
          }
        }
      }
    remote.netty.tcp.port = 8090
}

receiver.conf

include "application"
akka {
    remote.netty.tcp.port = 8091
}

Receiver.java

package com.aliyesilkanat.akkadeneme.receiver;

import com.aliyesilkanat.akkadeneme.Messages;

import akka.actor.UntypedActor;

public class Receiver extends UntypedActor {

    @Override
    public void onReceive(Object msg) throws Exception {
        if (msg.equals(Messages.RECEIVE)) {
            System.out.println("receiver receives");
        }
    }

}

ReceiverApplication.java

package com.aliyesilkanat.akkadeneme.receiver;

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;

import com.typesafe.config.ConfigFactory;

public class ReceiverApplication {
    public static void main(String[] args) {
        startRecieverSystem();
    }

    private static void startRecieverSystem() {
        final ActorSystem system = ActorSystem.create("ReceiverSystem",
                ConfigFactory.load("receiver"));
        ActorRef actorOf = system.actorOf(Props.create(Receiver.class),
                "receiverActor");
        System.out.println("created receiver actor: " + actorOf.toString());
    }
}

Sender.java

package com.aliyesilkanat.akkadeneme.sender;

import akka.actor.ActorSelection;
import akka.actor.UntypedActor;

import com.aliyesilkanat.akkadeneme.Messages;

public class Sender extends UntypedActor {

    public Sender() {
    }

    @Override
    public void onReceive(Object msg) throws Exception {
        if (msg.equals(Messages.SEND)) {
            System.out.println(getSender() + " sends");
            ActorSelection receiverActor = getContext().actorSelection(
                    "akka.tcp://ReceiverSystem@127.0.0.1:8091/user/receiver"); // I am not sure about this one
            receiverActor.tell(Messages.RECEIVE, getSelf());
        }
    }

}

SenderApplication.java

package com.aliyesilkanat.akkadeneme.sender;

import com.typesafe.config.ConfigFactory;

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;

public class SenderApplication {
    private static ActorSystem system;

    public static void main(String[] args) {
        startSenderApp();
    }

    private static void startSenderApp() {
        setSystem(ActorSystem.create("SenderSystem",
                ConfigFactory.load("sender")));
        ActorRef actorOf = getSystem().actorOf(Props.create(Sender.class),
                "senderActor");
        System.out.println("created sender actor: " + actorOf.toString());
    }

    public static ActorSystem getSystem() {
        return system;
    }

    public static void setSystem(ActorSystem system) {
        SenderApplication.system = system;
    }
}

最后,主要方法

public static void main(String[] args) {
    ReceiverApplication.main(null);
    SenderApplication.main(null);
    ActorSystem system = SenderApplication.getSystem();
    ActorSelection ref = system.actorSelection("sender");
    ref.tell(Messages.SEND, ActorRef.noSender());
}

整个控制台输出

[INFO] [08/15/2015 12:48:12.220] [main] [Remoting] Starting remoting
[INFO] [08/15/2015 12:48:12.451] [main] [Remoting] Remoting started; listening on addresses :[akka.tcp://ReceiverSystem@127.0.0.1:8091]
[INFO] [08/15/2015 12:48:12.451] [main] [Remoting] Remoting now listens on addresses: [akka.tcp://ReceiverSystem@127.0.0.1:8091]
created receiver actor: Actor[akka://ReceiverSystem/user/receiverActor#2084584126]
[INFO] [08/15/2015 12:48:12.481] [main] [Remoting] Starting remoting
[INFO] [08/15/2015 12:48:12.491] [main] [Remoting] Remoting started; listening on addresses :[akka.tcp://SenderSystem@127.0.0.1:8090]
[INFO] [08/15/2015 12:48:12.491] [main] [Remoting] Remoting now listens on addresses: [akka.tcp://SenderSystem@127.0.0.1:8090]
created sender actor: Actor[akka://SenderSystem/user/senderActor#-2012370784]
[INFO] [08/15/2015 12:48:12.491] [SenderSystem-akka.actor.default-dispatcher-3] [akka://SenderSystem/sender] Message [com.aliyesilkanat.akkadeneme.Messages$1] from Actor[akka://SenderSystem/deadLetters] to Actor[akka://SenderSystem/sender] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

2 个答案:

答案 0 :(得分:0)

ActorSystem是本地(相同的JVM)时,则呼叫为akka://ActorSystem/user/ActorName。在你的主要方法是:

ActorSelection ref = system.actorSelection("sender");

尝试替换sender

akka://SenderSystem/user/senderActor

答案 1 :(得分:0)

你有发件人conf,远程部署,所以你可以从Sender actor远程创建Receiver actor

ActorRef actor = system.actorOf(Props.create(Receiver.class), "receiver");
actor.tell(Messages.SEND, ActorRef.noSender());