当前位置: 首页 > 知识库问答 >
问题:

当发送消息后父级停止时,从父级参与者到子级参与者的消息上的死信

广宏远
2023-03-14

考虑下面的代码示例(版本1)。在这里,父角色(ActorA)向子角色(ActorB)发送消息,然后停止自我。由于父角色的自停止,在高负载下,子角色甚至在从邮箱提取邮件之前就会死亡,因此邮件变成了“死信”(参见下面的示例输出1)。

由于某些原因,我无法修改应用程序设计以删除父参与者的自停止。

版本1

import akka.actor.Actor
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Stop
import akka.actor.Props
import akka.actor.ActorSystem

object AkkaTest extends App {

  val system = ActorSystem("AkkaTest")

  for (i <- 1 to 5) {
    system.actorOf(Props[ActorA]) ! i  
  }

}

class ActorA extends Actor {

  def receive = {
    case i: Int => { 
      context.actorOf(Props[ActorB]) ! i
      context.stop(self)
    }
  }

  override def postStop = println("ActorA - stopped")

}

class ActorB extends Actor {

  def receive = {
    case i: Int => {
      println("ActorB - processing msg - " + i)
    }
  }

  override def postStop = println("ActorB - stopped")

}

样本输出1

ActorB - processing msg - 2
ActorB - processing msg - 1
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - processing msg - 3
ActorB - stopped
ActorA - stopped
ActorA - stopped
[INFO] [09/09/2014 08:26:56.101] [AkkaTest-akka.actor.default-dispatcher-6] [akka://AkkaTest/user/$e/$a] Message [java.lang.Integer] from Actor[akka://AkkaTest/user/$e#-289783076] to Actor[akka://AkkaTest/user/$e/$a#-86921027] 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'.
[INFO] [09/09/2014 08:26:56.101] [AkkaTest-akka.actor.default-dispatcher-3] [akka://AkkaTest/user/$d/$a] Message [java.lang.Integer] from Actor[akka://AkkaTest/user/$d#-1255514179] to Actor[akka://AkkaTest/user/$d/$a#402128903] was not delivered. [2] 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'.
ActorA - stopped
ActorA - stopped
ActorA - stopped

现在考虑下面的代码修改(版本2)。通过将消息确认从子参与者引入到父参与者,然后在收到此确认时自动停止父参与者,可以消除死信(请参阅示例输出2)。

版本2

import akka.actor.Actor
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Stop
import akka.actor.Props
import akka.actor.ActorSystem

object AkkaTest extends App {

  val system = ActorSystem("AkkaTest")

  for (i <- 1 to 5) {
    system.actorOf(Props[ActorA]) ! i  
  }

}

class ActorA extends Actor {

  def receive = {
    case i: Int => context.actorOf(Props[ActorB]) ! i
    case m: MsgAck => context.stop(self) 
  }

  override def postStop = println("ActorA - stopped")

}

class ActorB extends Actor {

  def receive = {
    case i: Int => {
      sender ! MsgAck()
      println("ActorB - processing msg - " + i)
    }
  }

  override def postStop = println("ActorB - stopped")

}

case class MsgAck()

样本输出2

ActorB - processing msg - 4
ActorB - processing msg - 2
ActorB - processing msg - 5
ActorB - processing msg - 3
ActorB - processing msg - 1
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorA - stopped
ActorA - stopped
ActorA - stopped
ActorA - stopped
ActorA - stopped

现在我的问题是,有没有其他方法可以达到同样的效果?我的意思是扔掉死信。

共有1个答案

公羊凌
2023-03-14

当一个父级被停止时,它的所有子级都将被停止。这就是死信的原因。确保没有死信的唯一方法是确保父母活着,直到孩子收到消息。除了ack消息之外,我想不出任何其他方法

 类似资料:
  • 问题内容: 我的问题是我需要它以相反的方式工作(子级到父级),并且不知道如何定位父级窗口。 这是我的接收方代码(在父级中)- 这是由简单形式(在子级中)触发的发送方功能- 我应该以其他方式定位父母吗? 干杯保罗 问题答案: var eventMethod = window.addEventListener ? “addEventListener” : “attachEvent”; var even

  • 我希望避免给终止的参与者发送死信消息,并避免向该参与者发送消息 actorSelection没有像我预期的那样工作,从ping发送的最后一条消息仍然以一纸空文告终: [信息][09/16/2016 00:47:46.237][MyActorSystem-Akka.Actor.Default-Dispatcher-4][Akka://MyActorSystem/User/PingActor/Pong

  • 我用的是Akka。NET来实现一个actor系统,其中一些actor是按需创建的,并在可配置的空闲时间后删除(我使用Akka的“ReceiveTimeout”机制)。这些参与者中的每一个都由一个密钥标识,并且不应该存在具有相同密钥的两个参与者。 这些参与者当前由一个普通主管创建和删除。可以要求主管返回与给定密钥匹配的参与者的引用,如果具有该密钥的参与者尚不存在,则可以返回现有的参与者,也可以创建新

  • 我对Akka演员和演员模型有点困惑。从参与者A发送到参与者B的消息是否保持顺序?如何在本地/网络环境中实现这一点?据我所知,网络引入了可变延迟,如果M1的延迟为1秒,M2为0.5秒,那么消息M1和消息M2如何保持顺序?

  • 我有一个简单的Kafka设置。生成器正在以较高的速率向单个分区生成具有单个主题的消息。单个使用者正在使用来自此分区的消息。在此过程中,使用者可能会多次暂停处理消息。停顿可以持续几分钟。生产者停止产生消息后,所有排队的消息都将由使用者处理。生产者产生的消息似乎不会立即被消费者看到。我使用的是Kafka0.10.1.0。这里会发生什么?下面是使用消息的代码部分: 代理上的所有配置都保留为kafka默认

  • 假设我有一个应用程序来处理一系列的书。 我的应用程序允许向库中添加新书。创建书籍时,用户可以在列表中选择作者,如果作者尚不存在,则可以将其添加到列表中,并在表单字段中提供其姓名。填写表单后,数据将发送到WS,类似 然后我将json映射到我的实体中 书: 作者 这不会像用户尝试添加新作者一样工作,当我尝试. sav()时,我会收到错误: 组织。冬眠TransientPropertyValueExce