性能文章>【译】一次交易类场景CPU飙升100%的故障排除案例>

【译】一次交易类场景CPU飙升100%的故障排除案例转载

1月前
356466

在本文中,我们将讨论如何解决北美主要交易应用程序中出现的 CPU 峰值问题。突然之间,这个应用程序的 CPU 开始飙升至 100%。事实上,这个团队没有进行任何新的代码部署,没有进行任何环境更改,也没有翻转任何标志设置——但突然间,CPU 开始飙升。我们甚至验证了流量是否增加,这归因于流量峰值。但交通量也没有增加。

数据采集

该应用程序运行在 Java、Tomcat 技术栈上。我们要求可靠性工程 (SRE) 团队从发生此问题的服务器中做了以下两步:

1. top-h 输出

2. Thread dumps

结果:

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 和内存量。下面是我们从这个交易应用程序中得到的输出:

图:顶部 -H -p {pid}

从“top -H”输出中可以看出,第一行有一个 id 为 '11956' 的线程。仅此线程就消耗了 60.9% 的 CPU。答对了!!这是第一场胜利。现在使用这个'top -H'选项,我们已经确定了消耗大量CPU的线程。

2.  Thread dumps

我们的下一个挑战是识别这个“11956”线程正在执行的代码行。这是线程转储派上用场的地方。线程转储显示应用程序中运行的所有线程及其代码执行路径(即堆栈跟踪)。此博客重点介绍了 8 个不同的选项来捕获线程转储。您可以使用方便的选项。我们使用 JDK 中的“jstack”工具来捕获线程转储。

最佳实践:捕获至少 3 个线程转储,每个线程转储之间的间隔为 10 秒。

分析数据

现在我们将“top -H”输出和“线程转储”都上传到了fastThread工具。如果您不确定如何将“top -H”输出和线程转储上传到 fastThread 工具,这里是它的说明。该工具能够分析线程转储和“top -H”输出并生成直观的报告。该工具分析并生成了这份漂亮的报告

此报告包含“CPU | 记忆”部分。这是该工具结合 top -H 输出和线程转储并提供应用程序中每个线程消耗的 CPU 和内存的部分。

图:CPU,每个线程消耗的内存(由 fastThread 生成)

在上面的屏幕截图中,我们可以看到第一行中的“WebContainer:18”线程报告正在消耗“60.9%”的 CPU。在最后一列,您可以看到该线程的代码执行路径(即堆栈跟踪)。您可以看到该工具现在报告线程名称(即“WebContainer:18”)和它正在执行的代码路径(当我们看到原始的 top -H 输出时,它不可用)。

图:高 CPU 消耗线程的 Stacktrace(由 fastThread 生成)

解决方案

您可以注意到“WebContainer: 18”线程正在执行 java.util.WeakHashMap#put() 代码行。对于不知道的人来说,HashMap 不是线程安全的实现。当多个线程同时调用 HashMap 的 get() 和 put() 方法时,可能会导致无限循环。当线程无限循环时,CPU 消耗将开始飙升。这就是这个应用程序中发生的确切问题。一旦 WeakHashMap 被 ConcurrentHashMap 替换,问题就解决了。

我们希望您发现这种简单的技术很有用。 

 

原文地址:https://blog.fastthread.io/2020/04/23/troubleshooting-cpu-spike-in-a-major-trading-application/

原文作者:fastthread团队

点赞收藏
willberthos

keep foolish!

请先登录,查看6条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

mcp内核稳定性问题定位思路与方法

mcp内核稳定性问题定位思路与方法

深入理解Linux系统调用与API

深入理解Linux系统调用与API

【全网首发】从 Linux 内核角度探秘 JDK NIO 文件读写本质

【全网首发】从 Linux 内核角度探秘 JDK NIO 文件读写本质

怒啃 24 小时,终于搞懂上下文切换!

怒啃 24 小时,终于搞懂上下文切换!

嵌入式linux-CPU性能优化小记

嵌入式linux-CPU性能优化小记

平均负载与 CPU 使用率,到底有啥区别?

平均负载与 CPU 使用率,到底有啥区别?

6
6