Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 询问vs告诉或转发使用Akka流的演员_Java_Akka_Akka Stream - Fatal编程技术网

Java 询问vs告诉或转发使用Akka流的演员

Java 询问vs告诉或转发使用Akka流的演员,java,akka,akka-stream,Java,Akka,Akka Stream,您好,我与akka streams以及akka stream kafka一起工作。我正在使用以下设置设置流: Source (Kafka) --> | Akka Actor Flow | --> Sink (MongoDB) Actor Flow主要由处理数据的Actor进行,下面是层次结构: System |

您好,我与
akka streams
以及
akka stream kafka
一起工作。我正在使用以下设置设置流:

Source (Kafka) --> | Akka Actor Flow | --> Sink (MongoDB)
Actor Flow
主要由处理数据的Actor进行,下面是层次结构:

                                      System
                                         | 
                                     Master Actor  
                                      /       \
                          URLTypeHandler     SerializedTypeHandler
                             /       \                   |
                     Type1Handler   Type2Handler     SomeOtherHandler
卡夫卡有一条信息,我写下消费者并在
atmostonesource
configuration and use中运行它

Consumer.Control control =
            Consumer.atMostOnceSource(consumerSettings, Subscriptions.topics(TOPIC))
                    .mapAsyncUnordered(10, record -> processAccessLog(rootHandler, record.value()))
                    .to(Sink.foreach(it -> System.out.println("FinalReturnedString--> " + it)))
                    .run(materializer);
我最初使用打印作为水槽,只是为了让流程运行

processAccessLog
的定义如下:

private static CompletionStage<String> processAccessLog(ActorRef handler, byte[] value) {

    handler.tell(value, ActorRef.noSender());

    return CompletableFuture.completedFuture("");
}
私有静态CompletionStage processAccessLog(ActorRef处理程序,字节[]值){
tell(value,ActorRef.noSender());
返回CompletableFuture.completedFuture(“”);
}
现在,根据定义,当参与者期望响应时必须使用
ask
,在这种情况下是有意义的,因为我希望返回要写入接收器中的值

但是每个人(包括文档)都提到避免询问,而是使用告诉和转发,这是一个很棒的博客

在他提到的博客中,如果是嵌套的参与者,则对第一条消息使用
tell
,然后对到达目的地的消息使用
forward
,然后在处理后直接将消息发送回根参与者

现在问题来了

  • 如何将消息从D发送回A,以便我仍然可以使用接收器
  • 开放式流是一种良好的做法吗?e、 g.水槽不重要的溪流,因为演员已经完成了工作。(我认为不建议这样做,似乎有缺陷)
    询问
    仍然是正确的模式

    从链接的博客文章来看,
    ask
    的一个“缺点”是:

    阻止参与者本身,直到 响应到达,处理完成

    然而,在akka stream中,这正是我们正在寻找的特征,也称为“背压”。如果
    接收器
    处理数据需要很长时间,那么我们希望
    的速度减慢

    作为旁注,我认为在博客文章中声称额外的监听器
    Actor
    会导致一个“几十倍重”的实现是夸张的。显然,中间参与者会增加一些延迟开销,但不会增加更多

    消除背压

    任何你正在寻找的实现都将有效地消除背压。仅使用
    tell
    的中间流将持续将需求传播回源,而不管处理程序参与者中的处理逻辑是否以源生成数据的相同速度完成其计算。 考虑一个极端的例子:如果你的源可以每秒产生100万条消息,但是通过<代码>接收这些消息的参与者告诉每秒只能处理1条消息。那个演员的邮箱会怎么样

    通过有目的地链接处理程序的速度和源生成数据的速度


    如果你愿意移除从水槽到源头的背压信号,那么你最好首先不要使用akka stream。您可以使用背压或非阻塞消息,但不能同时使用两者。

    Ramon J Romero y Vigil是正确的,但我将尝试扩展响应

    1) 我认为“不问就说”的教条主要是针对参与者系统架构的。在这里,您需要返回Future,以便流可以解析处理后的结果,您有两个选项:

    • 使用询问
    • 为每个事件创建一个参与者,并向他们传递承诺,这样,当该参与者收到数据时,未来将是完整的(您可以使用
      getSender
      方法,以便D可以将响应发送给a)。没有办法在信息中传达承诺或未来(这些信息不可连载),因此无法避免创造这种短命演员
    最后,你也在做同样的事情

    2) 使用一个空的接收器来完成流是非常好的(实际上akka提供了
    Sink.ignore()
    方法来完成)


    似乎您缺少了使用流的原因,它们是提供可组合性、并发性和背压的很酷的抽象。另一方面,演员无法作曲,难以承受背压。如果您不需要这些功能,而且您的演员可以轻松完成工作,那么您首先不应该使用akka streams。

    感谢您的精彩解释,我最后做的是使用
    .mapsyncUnordered(10,record->ask(ActorA,record.value()处理我的流)
    ,然后是来自
    ActorA->ActorB->ActorC
    forward
    ,ActorC使用
    getSender().tell(myResponse,ActorRef.noSender());
    。然后利用
    Sink
    对所有仍应传播背压的外部数据存储进行处理(根据我的理解)@iam.Carrot不客气。只要涉及到一个ask,那么是的,背压就会传播。很快,执行
    ActorRef.ask()是否相关
    如果你有一个完整的演员系统来处理
    Sink
    ,那么在
    Sink
    也可以。或者,即使我们有
    告诉
    非常感谢你的回答,特别是在第二点上,因为我很担心它。+1