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

Akka执行元消息传递延迟

鲁展
2023-03-14

我遇到了在多个请求下扩展应用程序的问题。

每个请求都向一个参与者发送一个ask,然后生成其他参与者。这是很好的,但是,在负载下(一次5个以上的询问),ask会花费大量的时间将消息传递给目标执行元。最初的设计是均匀地隔离请求,但这造成了一个瓶颈。示例:

在此图片中,ask是在查询计划解析程序之后发送的。但是,当执行元接收到此消息时有一个多秒的间隔。这只在负载(5+请求/秒)下才会出现。我最初以为这是一个饥饿的问题。

设计:每个计划执行器都是每个请求的一个独立实例。它每次都生成一个新的“请求接受器”执行元(它在接收到消息时记录“请求分数”)。

  • 我为actorsystem提供了一个自定义全局执行器(大执行器)。我注意到,即使在这个巨大的延迟期间,线程的使用也没有超出核心线程池的大小
  • 我确保子执行元中的所有ExecutionContext
  • 使用了正确的ExecutionContext
  • 确保参与者内部的所有阻塞调用都使用了将来的调用
  • 我给父执行元(和所有子执行元)一个核心大小为50且最大大小为100的自定义调度器。即使在这些延迟期间,它也没有请求更多(停留在50个)
  • 最后,我尝试为每个请求创建一个全新的Actorsystem(在planner-executor内部)。这也没有明显的影响!

我有点被这个难住了。从这些测试来看,它看起来不像是一个线程饥饿问题。回到起点,我不知道为什么消息需要越来越长的时间来传递我发出的并发请求。到达此点之前的Zipkin跟踪不会随着更多的请求而降级,直到它到达这里的ask。在此之前,服务器能够处理多个步骤,例如veify请求,与db对话,然后最后进入规划器-执行器。所以我怀疑应用程序本身的cpu时间不够用。

共有1个答案

鱼志诚
2023-03-14

我们和Akka也有类似的问题。在peek加载时,我们观察到ask模式将消息传递给目标参与者的延迟很大。

这些问题大多与堆内存消耗有关,而不是因为调度器的使用。

最后,我们通过调整下面的一些配置和更改来解决这些问题。

1)确保停止不再需要的实体/执行元。如果它是一个持久执行元,那么您总是可以在需要时将它带回来。参考:https://doc.akka.io/docs/akka/current/cluster-sharding.html#passivation

3)最小化日志条目(将其设置为info级别)。

4)调整日志以频繁地将消息发布到日志系统。相应地更新批大小、批计数和间隔。以便释放内存。在我们的情况下,巨大的堆内存用于缓冲日志消息并批量发送。如果间隔更长,则可能会填满堆内存,从而影响性能(需要更多的GC活动)。

5)在单独的调度程序上运行阻塞操作。

6)使用自定义序列化器(protobuf)并避免使用JavaSerializer。

7)将以下java_opt添加到jar中

export java_opts=“$java_opts-xx:+UnlockExperimentalVmOptions-xx:+usecGroupMemoryLimitForHeap-xx:MaxRamFraction=2-djava.security.egd=file:/dev/./urandom”

最主要的是xx:maxRamFraction=2,它将占用60%以上的可用内存。默认情况下,它的4意味着您的应用程序将只使用可用内存的四分之一,这可能是不够的。

参见:https://blog.csanchez.org/2017/05/31/running-a-jvm-in-a-container-without-get-kill/

问候,

维诺特

 类似资料:
  • 此应用程序收到 但是,当不存在web套接字会话,并且JMSProducer将消息发送到QueueSenderSessionBean中的目标“jms/notificationQueue”时,消息会立即在NotificationEndpoint中使用。这不是我的意图。 我的目的是让队列保留消息,直到用户连接到NotificationEndpoint。如果用户没有连接到NotificationEndpo

  • 我有相当多的Apache Camel(路由/中介/Orchestation Engine;轻量级ESB)经验,正在绞尽脑汁地试图理解AKKA: 调度程序(,,) 路由器 池 组 事件总线 根据文件: 调度员是: 将路由创建为子参与者,并在路由终止时将其从路由器中删除的路由器的[一种类型]。 组包括: [一种类型的]执行元[其中路由]是在路由器外部创建的,路由器使用执行元选择将消息发送到指定路径,而

  • spring XML中的jmsTemplate定义: 有人对问题有什么建议吗/关于如何实现延迟消息传递的其他想法?谢了!

  • 标题是不言自明的,我希望能够向父执行元发送消息(意味着我希望父执行元的)。在Akka Classic(非类型化)中,父执行元的可以通过以下方式从子执行元的获得: (例如,参见这个问题(在Java))。 但是,Akka Typed中的不公开父级的。Scala中是否有惯用的方法为父执行元获取?

  • 我的问题与Spring JMS(ActiveMQ)延迟传递消息非常相似,但与Spring boot自动配置程序更相关 我试图使用方法,但它抛出了一个 我试着从他那里找到合适的房产http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html但找不到broker sche

  • 由于内容脚本在网页而不是扩展程序的上下文中运行,因此它们通常需要某种与扩展程序其余部分进行通信的方式。例如,RSS 阅读器扩展程序可以使用内容脚本来检测页面上 RSS 摘要的存在,然后通知后台页面以显示该页面的操作图标。 扩展及其内容脚本之间的通信使用消息传递来实现。任何一方都可以监听从另一端发送的消息,并在同一通道上进行响应。消息可以包含任何有效的 JSON 对象(空,布尔值,数字,字符串,数组