Akka IO 应用消耗 100% cpu
Posted
技术标签:
【中文标题】Akka IO 应用消耗 100% cpu【英文标题】:Akka IO app consumes 100% cpu 【发布时间】:2016-10-27 14:38:32 【问题描述】:我正在尝试分析始终处于或接近 100% CPU 使用率的 Akka 应用程序。我使用visualvm
采集了一个 CPU 样本。该样本表明有 2 个线程占 CPU 使用率的 98.9%。 79% 的 cpu 时间花在了一个名为 sun.misc.Unsafe
的方法上。 Other answers on SO 说它只是意味着一个线程正在等待,但在本机实现层(在 jvm 之外)。
在与我类似的问题中,人们一直 told to look elsewhere 没有给出具体细节。我应该从哪里找出导致 cpu 峰值的原因?
应用程序是一个服务器,主要使用 Akka IO 来监听 TCP 套接字连接。
【问题讨论】:
您说您采集了 CPU 样本。你到底是什么意思? sun.misc.Unsafe 不是一种方法,它是一个类。请显示完整的堆栈跟踪。 我在actor中尝试使用Spring Rest Template客户端时遇到了类似的问题:***.com/questions/49301174/… 【参考方案1】:没有看到任何源代码,甚至不知道您在谈论什么 IO 通道(套接字、文件等),这里的任何人都无法为您提供任何见解。
不过,我确实有一些比较笼统的建议。
首先,您应该在应用程序中使用响应式技术和响应式 IO。 出现此问题的原因可能是您在紧密循环中轮询某些资源的状态,或者在以下情况下使用阻塞调用你应该使用一个反应式的。这往往是一种反模式和性能消耗,正是因为您可以将 CPU 周期花费在“积极等待”之外什么都不做。我建议仔细检查:
资源轮询 阻止呼叫 系统调用 磁盘刷新 等待Future
何时适合 map
代替
其次,您不应该在您的应用程序中使用互斥锁或其他线程同步。如果是这样,那么您可能遇到了活锁。与死锁不同,活锁表现为 100% CPU 使用率之类的症状,因为线程不断锁定和解锁并发原语以试图“全部捕获”。 Wikipedia 对活锁的外观有很好的技术描述。使用 Akka,您应该不需要使用互斥锁或任何线程同步原语。如果您是,那么您可能需要重新设计您的应用程序。
第三,您应该限制 IO(以及重新连接尝试等错误处理)。 出现此问题的原因可能是您的系统缺乏有效的限制。通常,对于数据通道,我们会使其带宽不受限制。但是,当该通道达到 100% 饱和并开始从系统的其他部分窃取资源时,这可能会成为一个问题。例如,如果您在没有合理限制的情况下移动大文件,就会发生这种情况。
或者,您还需要在遇到任何错误时限制连接重试,而不是立即重试。如果失去连接,许多系统将尝试重新连接到服务器。虽然通常是可取的,但如果您使用天真的重新连接策略,这可能会导致问题行为。例如,想象一个这样编写的网络客户端:
class MyClient extends Client
... other code...
def onDisconnect() =
reconnect()
每当客户端因任何原因断开连接时,它都会尝试重新连接。您可以看到如果 Wifi 中断或网络电缆被拔下,这将如何导致错误处理代码和客户端之间的紧密循环。
第四,您的应用程序应该有明确定义的数据源和接收器。您的问题可能是由“数据循环”引起的,即某些 Akka 参与者只是将消息发送到下一个链中的参与者,最后一个参与者将消息发送回链中的第一个参与者。确保您有一个清晰明确的方式让消息进入和退出您的系统。
第五,为您的应用程序使用适当的分析和检测。使用 Kamon 或 Coda Hale 的 Metrics 库检测您的应用程序。
找到合适的分析器会更加困难,因为作为一个社区,我们在为响应式应用程序开发成熟工具方面还有很长的路要走。我个人发现visualvm
很有用,但对于检测受 CPU 限制的代码路径并不总是非常有用。问题是采样分析器只能在 JVM 达到安全点时收集数据。这有可能偏向某些代码路径。解决方法是使用支持AsyncGetStackTrace
的分析器。
祝你好运!如果可以,请添加更多上下文。
【讨论】:
以上是关于Akka IO 应用消耗 100% cpu的主要内容,如果未能解决你的问题,请参考以下文章
Valgrind 挂在 pthread_spin_lock 消耗 100% CPU
如何找出 Node.js 服务器 CPU 100% 的原因?
node.js 应用程序突然以 100% 加载 CPU 并挂起