有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Akka Java:遇到死信

我正在用akka库用java创建actors来实现Chord系统。 我的目标是让两个演员互相传递信息。 但当我这样做时,我会收到以下错误消息:

[INFO] [12/24/2015 15:27:33.521] [globalSystem-akka.actor.default-dispatcher-5] [akka://globalSystem/user/ChordActor3] Message [messages.SuccessorFoundMessage] from Actor[akka://globalSystem/user/ChordActor0#1781934127] to Actor[akka://globalSystem/user/ChordActor3#-2019697728] 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'.

以下是我的主要课程代码:

package classes;

import messages.JoinMessage;
import messages.PrintFingerTableMessage;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;

public class Main {

public static void main(String[] args) {

    final ActorSystem system = ActorSystem.create("globalSystem");


    ChordNode cn0 = new ChordNode(0);
    ChordNode cn3 = new ChordNode(3);


    final ActorRef actor0 = system.actorOf(Props.create(ChordActor.class),"ChordActor0");
    final ActorRef actor3 = system.actorOf(Props.create(ChordActor.class),"ChordActor3");


    PrintFingerTableMessage printFingerTableMessage = new PrintFingerTableMessage();
    JoinMessage joinMessage0 = new JoinMessage(cn0);
    JoinMessage joinMessage3 = new JoinMessage(cn3);


    actor0.tell(joinMessage0,null);
    actor0.tell(printFingerTableMessage,null);  

    actor3.tell(joinMessage3, actor0);
    actor3.tell(printFingerTableMessage,null);  


    system.shutdown();
}

}

这是我班的合唱演员:

package classes;

import java.util.ArrayList;

import messages.FindSuccessorMessage;
import messages.JoinMessage;
import messages.PrintFingerTableMessage;
import messages.SuccessorFoundMessage;
import akka.actor.ActorRef;
import akka.actor.UntypedActor;

public class ChordActor extends UntypedActor{
    private ChordNode chordNode;
    private FingerTable fingerTable;
    private ArrayList<Key> key = new ArrayList<Key>();
    private ActorRef predecessor;
    private ActorRef successor;

@Override
public void onReceive(Object message) throws Exception {


    if(message instanceof JoinMessage){
        this.chordNode=((JoinMessage) message).getChordNode();

        // if sender is null :
        if(getSender().toString().equals("Actor[akka://globalSystem/deadLetters]")){
            this.fingerTable= new FingerTable(this.chordNode,getSelf());
            this.predecessor=getSelf();
            this.successor=getSelf();
        }


        else{

            this.fingerTable= new FingerTable(this.chordNode);
            for(int i=0;i<this.fingerTable.getTable().size();i++){
                FindSuccessorMessage findSuccessorMessage = new FindSuccessorMessage(this.fingerTable.getTable().get(i).getLowBound(),i);
                getSender().tell(findSuccessorMessage, getSelf());
            }
        }
    }


    else if(message instanceof FindSuccessorMessage){
        ActorRef actorRef = this.fingerTable.findSuccessor(((FindSuccessorMessage) message).getId());
        int ligne = ((FindSuccessorMessage) message).getLigne();

        SuccessorFoundMessage successorFoundMessage = new SuccessorFoundMessage(actorRef,ligne);
        getSender().tell(successorFoundMessage,getSelf());
    }


    else if(message instanceof SuccessorFoundMessage){
        this.fingerTable.getTable().get(((SuccessorFoundMessage) message).getligne()).setSuccessor(((SuccessorFoundMessage) message).getActorRef());
    }

    else if(message instanceof PrintFingerTableMessage){
        System.out.println(this.fingerTable);       
    }
}
}

我在互联网上搜索解决方案,但我真的不知道如何解决我的问题

谢谢你的帮助

祝你今天愉快

乔纳森


共 (1) 个答案

  1. # 1 楼答案

    当您system.shutdown()您的参与者系统时,这将导致参与者停止。由于您不会以任何方式等待参与者的“工作”完成,因此当主方法终止系统时,参与者可能已经处理了所有消息,也可能没有处理任何消息

    如果某个参与者被停止时收件箱中有消息,它们将被发送到deadLetters(在这里的文档中描述:http://doc.akka.io/docs/akka/2.4.1/java/untyped-actors.html#Stopping_actors

    因此,我猜想您已经在参与者的收件箱中放置了消息,其中包含对tell的4个调用,但随后终止,并且由于它是异步的,因此无法确定参与者是否已经处理了消息。当您的参与者关闭时,收件箱中留下的消息将被发送到deadLetters

    我不确定示例代码中的参与者“完成”时是否有最终状态,因此,考虑到这一点,使其工作的一种方法是阻塞例如StdIn.readLine();然后shutdown系统,这样您就可以轻松地尝试一些东西,并自行决定要运行应用程序多长时间