发布于:2021-01-14 10:08:08
0
221
0
这篇文章研究了如何解决北美主要交易应用程序中的CPU高峰的示例。查看是什么原因导致了该问题,如何解决该问题以及您可以从中汲取哪些教训。
在本文中,我们将讨论如何解决在北美主要交易应用程序中出现的CPU高峰问题。突然,此应用程序的CPU开始飙升至100%。
实际上,这个团队没有进行任何新的代码部署,也没有进行任何环境更改,也没有翻转任何标志设置-但是突然之间,CPU开始出现故障。
我们甚至验证了流量是否有所增加,这归因于流量的激增。但是流量也没有增加。
数据采集
该应用程序在Java,Tomcat技术堆栈上运行。我们要求站点可靠性工程(SRE)团队从发生此问题的机器上捕获以下两个工件:
1. top -H输出
2.线程转储
让我们看看这些工件在本节中包含什么。
1. top -H
总是由于线程导致CPU峰值。因此,我们必须隔离导致此CPU峰值的线程。显然,此应用程序具有数百个线程。从这数百个线程中,我们需要确定导致CPU消耗激增的线程?这是第一个挑战。
这是“ top” unix命令行实用程序工具派上用场的地方。你们中的大多数人可能都熟悉“ top” unix命令行实用程序。此工具显示设备上正在运行的所有进程。它还显示了每个进程所消耗的CPU,内存。
该工具有一个秘密的“ -H”选项,许多工程师对此并不熟悉。可以这样调用:
$ top -H -p <PID>
PID是您的应用程序的流程ID。显然,此应用程序的进程ID为31294。因此SRE团队发出了此命令。
$ top -H -p 31294
当使用“ -H”选项调用“ top”工具时,它将开始显示该特定进程中正在运行的所有线程。它还将显示该进程中每个线程消耗的CPU和内存量。以下是我们从该交易应用程序获得的输出:
从“ top -H”输出中可以看到,第一行中有一个ID为“ 11956”的线程。仅此线程就消耗60.9%的CPU。答对了!!这是第一个胜利。现在使用此“ top -H”选项,我们已经确定了正在消耗大量CPU的线程。
线程转储
我们的下一个挑战是识别此“ 11956”线程正在执行的代码行。这是线程转储很方便的地方。线程转储显示了应用程序中正在运行的所有线程及其代码执行路径(即堆栈跟踪)。
重点介绍了捕获线程转储的8个不同选项。您可以使用方便的选项。我们使用了JDK的“ jstack”工具来捕获线程转储。
分析数据
现在,我们将“ top -H”输出和“线程转储”都上传到fastThread工具。如果您不确定如何将“ top -H”输出和线程转储上传到fastThread工具,请参见以下说明。
该工具能够分析线程转储和“ top -H”输出并生成直观的报告。这个工具分析并生成了这个漂亮的报告。
此报告包含“ CPU | 内存”部分。该部分将工具与top -H输出和线程转储结合在一起,并提供应用程序中每个线程消耗的CPU和内存。
在上面的屏幕截图中,我们可以看到第一行的“ WebContainer:18”线程报告正在消耗“ 60.9%” CPU。
在最后一列上,您可以看到此线程的代码执行路径(即堆栈跟踪)。您可以看到该工具现在报告线程名称(即'WebContainer:18')和它正在执行的代码路径(当我们看到原始top -H输出时不可用)。
解析度
您会注意到“ WebContainer:18”线程正在执行java.util.WeakHashMap#put()行代码。对于不知道的人,HashMap不是线程安全的实现。当多个线程同时调用HashMap的get()和put()方法时,可能会导致无限循环。
当线程无限循环时,CPU消耗将开始飙升。这就是此应用程序中发生的确切问题。将WeakHashMap替换为ConcurrentHashMap后,问题已解决。
我们希望您发现此简单技术有用。
作者介绍