Akka Java : 遇到死信
Akka Java : dead letters encountered
我正在 java 中使用 akka 库创建演员来实现 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'.
这是我的 Main class 的代码:
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();
}
}
这是我的 class ChordActor :
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);
}
}
}
我在网上搜索了解决方案,但我并没有真正理解如何解决我的问题。
感谢您的帮助。
祝你有愉快的一天!
乔纳森
当您 system.shutdown()
您的演员系统时,这将导致演员停止。由于您不以任何方式等待您的参与者的 "work" 完成,因此当您的主要方法终止系统时,他们可能已经处理了所有或可能尚未处理 none 的消息。
如果 actor 停止时收件箱中有消息,它们将被发送到 deadLetters
(在此处的文档中描述:http://doc.akka.io/docs/akka/2.4.1/java/untyped-actors.html#Stopping_actors)。
因此,我的猜测是您已经通过对 tell
的 4 次调用将消息放入了 actor 的收件箱中,但随后终止,并且由于它是异步的,因此不确定您的 actor 是否已处理消息还没有。当您的演员关闭时,收件箱中留下的消息将发送到 deadLetters
.
我不确定当你的演员在你的示例代码中 "done" 时是否有最终状态,所以考虑到这一点,让它工作的一种方法是阻止例如 StdIn.readLine();
然后 shutdown
系统,这样你可以很容易地尝试一些东西并自己决定你想要 运行 你的应用程序的时间。
我正在 java 中使用 akka 库创建演员来实现 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'.
这是我的 Main class 的代码:
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();
}
}
这是我的 class ChordActor :
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);
}
}
}
我在网上搜索了解决方案,但我并没有真正理解如何解决我的问题。
感谢您的帮助。
祝你有愉快的一天!
乔纳森
当您 system.shutdown()
您的演员系统时,这将导致演员停止。由于您不以任何方式等待您的参与者的 "work" 完成,因此当您的主要方法终止系统时,他们可能已经处理了所有或可能尚未处理 none 的消息。
如果 actor 停止时收件箱中有消息,它们将被发送到 deadLetters
(在此处的文档中描述:http://doc.akka.io/docs/akka/2.4.1/java/untyped-actors.html#Stopping_actors)。
因此,我的猜测是您已经通过对 tell
的 4 次调用将消息放入了 actor 的收件箱中,但随后终止,并且由于它是异步的,因此不确定您的 actor 是否已处理消息还没有。当您的演员关闭时,收件箱中留下的消息将发送到 deadLetters
.
我不确定当你的演员在你的示例代码中 "done" 时是否有最终状态,所以考虑到这一点,让它工作的一种方法是阻止例如 StdIn.readLine();
然后 shutdown
系统,这样你可以很容易地尝试一些东西并自己决定你想要 运行 你的应用程序的时间。