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

Akka远程处理-询问routee不会返回答案

慕容聪
2023-03-14

我试图向一个演员询问一些事情,这个演员是在SmallestMailboxPool中远程创建的,但我似乎从未得到回应。我的感觉是,这是因为我将消息发送到路由器,但路由器是正在响应的参与者-不知道Akka询问的确切内部内容,我可以想象,回复的消息必须与消息发送到的位置相同。另一方面,这似乎是如此基本,我无法想象它会不起作用。

我使用播放框架2.3. x和Akka远程2.3.4

演员设置我有两台机器,这些机器上有两个演员。我将尽量使这个例子尽可能简短。

机器A/演员A

实际的ask是在机器A上启动的,我添加了一些println语句来显示参与者地址。代码如下。

class ActorA(remoteActor: ActorRef) extends Actor with ActorLogging {
    ...
    def receive() = {
        case a: String => {
            println("Remote actor: " + remoteActor)
            println("Self: " + self)
            // This is where I get a timeout because I never get a reply
            Await.result((remoteActor ? a), timeout.duration)
        }
    }
}

我在机器A上得到的输出如下:

Remote actor: Actor[akka.tcp://application@192.168.0.101:2552/user/actorB_6f9bac20-2302-4408-9a1b-feece8c20bc3#-1920529606]
Self: Actor[akka://application/user/9df0190a-11fb-438c-9124-4869d015fc4d#-867250738]

请注意,我传递给ActorA的ActorRef(称为远程Actor)是我在机器B上创建的val actorRef(见下文),具有Mailbox Pool。

机器B/演员B

在机器B上,我有一个在SmallestMailboxPool中创建的参与者B,它从参与者a(通过路由器)接收消息,然后回复。

创建过程如下:

// Creation of the mailbox/Router
val actorRef = Akka.system.actorOf(
    SmallestMailboxPool(1).props(
        // sourceActor is the actorRef of Actor A, living on machine A
        Props(ActorB, sourceActor)
    ),
    name = java.util.UUID.randomUUID.toString
)
println("Mailbox is: " + actorRef)

实际参与者B执行以下操作:

class ActorB(sourceActor: ActorRef) extends Actor with ActorLogging {
    println("I am: " + self)
    def receive() = {
        case a: String => {
            println("I got data from " + sender)
            println("Sending it back to: " + sourceActor)
            sourceActor ! d
        }
    }
}

我从演员乙那里得到的是以下印刷线条:

Mailbox is Actor[akka://application/user/actorB_6f9bac20-2302-4408-9a1b-feece8c20bc3#-1920529606]
I am Actor[akka://application/user/actorB_6f9bac20-2302-4408-9a1b-feece8c20bc3/$a#46262703]
I got data from Actor[akka.tcp://application@192.168.0.132:2552/temp/$e]
I am sending it back to: Actor[akka.tcp://application@192.168.0.132:2552/user/9df0190a-11fb-438c-9124-4869d015fc4d#-867250738]

所以我不明白的是,为什么ActorA的演员地址在ActorB一侧显示为temp/$e。还可以看到,ActorB从ActorA获取消息,ActorA将消息发送到路由器。ActorB然后正确地尝试回复ActorA,但它总是得到一个超时-这是因为ActorB的ActorRef/地址与路由器/邮箱不同吗?我还尝试发送回sender,而不是给定的sourceActor参数,但没有成功。

我知道我可以向邮箱询问所有路由,然后直接向他们发送一个询问(还没有尝试过),但这违背了邮箱池的全部用途。编辑:尝试了这个,也没用

编辑:

整个故事中最奇怪的是,如果我在机器A上创建ActorRef(例如,不远程创建),一切正常-我可以询问路由器的ActorRef,然后得到正确的答复。一旦在机器B上创建了ActorB,我就再也没有收到回复了。我还试着看看如果我只告诉ActorB而不关心结果继续执行ActorA,会发生什么。然后发生的事情是,我确实从ActorB收到了消息,这应该是我对原始询问的回应ActorB因此完全能够发送回ActorA,但出于某种原因,Akka不会将其用作对我最初询问的答复。。。


共有1个答案

廖臻
2023-03-14

我设法让它工作了。原来我正在传递一个ActorRef到它应该发送到的ActorB,但是在ActorA的询问时间,似乎Akka制作了某种实际上需要从ActorB发送到的临时演员(即。我不能只是发送给ActorA的ActorRef,我传递给ActorB并在之前存储)。使用发件人对我来说是一个解决方案。(虽然我仍然困惑为什么sender实际上不是我的ActorA)。

我的实际用例太复杂了,无法分享,但我为感兴趣的人举了一个小例子(这个问题不会发生,一切正常):https://github.com/ErikTromp/AkkaRemoteAskTest.它也使用Play的Iteratee库,因为这也是我的用例的一部分。

 类似资料:
  • 问题内容: 我正在尝试遵循一个非常简单的多处理示例: 但是,在我的Windows机器上,我无法获得结果(在ubuntu 12.04LTS上,它运行正常)。 如果我检查,则会看到以下内容: 如果我跑步,我总能得到。 如果我运行python解释器冻结,则等待获取永远不会出现的结果。 该示例非常简单,因此我认为这是与OS相关的低级错误(我在Windows 7上)。但是也许其他人有更好的主意? 问题答案:

  • 问题内容: 我正在存储看起来像这样的文档: 然后,我用各种侧边栏过滤器显示这些列表,这些过滤器用于分类和日期(按年,按月)。根据用户选择的选项,结果查询可能最终看起来像: 这似乎完全按预期工作,除了当我尝试添加构面时,我可以在日期等旁边加上小数字(1)等: 仅当我不在查询中包括范围时,此方法才有效。如果范围在那儿,我就不会得到任何回报。只是没有结果。即使我将刻面更改为另一个术语而不是日期,我也一无

  • 问题内容: 我试图比较两个相同类型的对象(在dosHave方法中),但是我从未返回过“ true”。这是我的代码: “ Osoba”类如下所示: 来自主代码: 无论我要使用什么输入,这部分都永远不会发生。“ kartoteka”是我当然进口的包裹。每个类都在单独的程序包中,但是使用它们没有问题。我已经尝试了一段时间,但没有任何帮助,似乎 从来都不是真的,但我不知道为什么。没有Boolean.TRU

  • 问题内容: 我正在使用Asp.net MVC3,并尝试在服务器上做一个简单的Ajax发布,它返回部分视图并在搜索过程中更新我的项目列表。 Ajax成功调用服务器,服务器通过发送部分视图进行响应。但是部分视图始终在新页面中呈现。我发现这是因为它不知道即将到来的ajax调用,因此它呈现了一个新页面。 我的控制器代码非常简单: 但是无论如何,Request.IsAjaxRequest()始终返回fals

  • 1.API 返回结构 返回结果(response)分为:状态码(status code)、头部(headers)、消息体(body)。其中算法的结果会以 JSON 格式放在消息体中。 如何从 HTTP 返回中分别获取这三部分信息,请参见所用 HTTP 库的文档。 解析 JSON 格式需要寻找所用语言的 JSON 库,参见 http://www.json.org/ 2.正常结果 状态码为 2xx的为

  • 我正在使用JBoss6.1、Spring3.2、hibernate验证以及最近启用的CORS支持。请求与GET方法配合良好。如果使用请求方法POST,我希望控制器返回405。但我得到的是http状态码400。我在jboss日志中启用了跟踪,发现spring返回了错误的处理程序。应用程序只有一个控制器接受POST请求方法,其余控制器定义为只接受GET方法。每当使用POST请求方法对这些控制器(用GE