试图了解当音量增加或所有接收参与者都忙于工作时,AKKA 集群的哪一层会偶尔向死者发送消息,以及如何调整它以消除这种行为。
这是基本拓扑:2 个节点。Node1 由一组参与者(我们称之为发布参与者)和 akka 集群感知路由器组成。发布参与者将消息发布到路由器(RoundRobin),然后路由器将消息路由到 Node2,该节点由工作参与者(不要称他们为订阅参与者)组成,这些参与者参与者接收消息并执行一些工作并回复发布路由器。
观察:在发布消息的高速率(对于 akka 而言,10 秒内 10K 并不高)和订阅者工作人员很忙的情况下,我看到双方偶尔会死去(发布者和订阅者演员回击)。后者的死亡率几乎是 30-40%,但在分析和注意到线程饥饿并为集群配置单独的调度程序和为订阅者工作人员配置 PinnedDispatcher 之后,我们能够将后者的死亡率降低到 1-2%。值得注意的是,当使用带有 for-join 线程池的默认调度程序并且参与者数量高于线程数量时,观察到后者的高死率;当参与者数量少于线程数量时,比率会低得多,这会导致我们惊异于其他 akka 系统处理正在使用 fork-join 池。Ram、GC 和 CPU 看起来都在控制之中。它使用默认的无界邮箱,因此与缓冲区无关。据我所知,akka 不会管理背压
当然,我们确实理解 akka 不保证交付,我们必须实现自己的重试逻辑。这里的主要尝试是了解导致死亡的原因:它是否发生在 akka 远程处理、netty 传输层……,是否有一些可以调整和配置的超时实现。
我花了相当多的时间进行分析,添加额外的日志记录,捕获死后的日志并记录,但没有得到任何关于实际原因的线索。
非常感谢任何提示、尝试的事情或其他信息
这是我们添加的配置:
cluster-dispatcher { type = "Dispatcher" executor = "fork-join-executor" fork-join-executor {
parallelism-min = 2
parallelism-max = 4 } }
#usde by worker worker-pinned-dispatcher { executor = "thread-pool-executor" type = PinnedDispatcher }