当分析器无法收集样本时,如何调试无响应的服务器?

Posted

技术标签:

【中文标题】当分析器无法收集样本时,如何调试无响应的服务器?【英文标题】:How can I debug a non-responsive server, when the profiler can't collect samples? 【发布时间】:2013-05-02 20:30:04 【问题描述】:

我编写的服务器偶尔会出现问题。它在 Clojure 中,但我认为这并不重要,我们可以假装它在 Java 中。无论如何,它一次可以正常工作几个小时,但会在表现非常糟糕的地方出现:所有活动停止,大约十五秒钟,然后它正常工作几秒钟,然后停止十五秒钟......所以(通常)大约十分钟左右,之后它会恢复正常行为。

我已经使用 YourKit 对其进行了很多分析,并排除了一些可能的嫌疑人:

这不是垃圾收集问题:我使用 -XX:+UseConcMarkSweepGC 运行它,并且我已经验证服务器在次要和主要收集期间继续运行良好,因为它的并发性质垃圾收集器。而且我们不会因为总内存耗尽或其他原因而崩溃:当前堆大小远低于其最大值。

我认为这不是锁定/同步问题,但我对此不是 100% 确定的。 YourKit 分析器有时会显示线程等待,例如争夺 System.out 的锁以生成日志消息,但唯一的长时间等待是线程池中的工作线程在无事可做时。当然,YourKit 说它从未检测到任何死锁。

这不是由于附加了探查器造成的,因为即使我启动服务器然后在没有附加探查器的情况下不理会它,它仍然会发生。

占用所有 CPU 时间的不是系统上的其他进程:top 显示我的 java 进程的 CPU 使用率为 100%,其他所有进程基本上为 0%。

我最大的问题是,在这些奇怪的恐惧中,我看不到服务器在 在做什么,因为分析器停止接收样本。这是CPU使用率图表:

图的左侧是正常操作,在此期间我们每秒左右获取分析器样本。右侧是“损坏的”,并且非常尖,因为分析器每十秒左右才获取样本。在它得到的样本中,服务器似乎在做它平常的事情:响应请求等等;并且日志确认它正在做正常的事情,但仅在分析器有样本时: 在图表上向上倾斜的“直线”期间,分析器没有样本,服务器什么也不做.

那么,这个图表对任何人来说都很熟悉吗?你以前有过这个问题并解决了吗?或者您能否指出一个工具的方向,该工具可以在 YourKit 无法确定我的服务器在做什么时?万一这很重要,服务器机器正在运行 Ubuntu 10.04,并且

$ java -version
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.10) (rhel-1.28.1.10.10.el5_8-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)

【问题讨论】:

这可能是一个巨大的痛苦,但您可以调试整个代码的日志记录,然后查看写入日志的内容。另一种可能是问题不在于您的 java 程序,而实际上是服务器上的其他作业占用了所有资源 10 分钟。 挂起时你需要得到is one (1) stack sample,然后检查并理解它。这不是关于测量——而是关于“它为什么挂起?”当然,正如 durron597 所说,可能不是您的代码有问题,因此您可能需要来自所有线程的示例。 这是一个好点,@durron,但是这台机器上没有运行其他有趣的东西,top 显示了 java 进程在其“悲伤时期”使用 100% CPU。我会将其编辑到问题中。正如我所提到的,我已经有相当多的日志记录了:当服务器卡住时,这些都不会发生。 即使使用 CMS,有时也会启动 stop-the-world full GC。您是否启用/检查了纯 GC 日志? @fglez 是的,并且还通过分析器观察了应用程序在 GC 期间的行为方式。我很有信心这不是与 GC 相关的问题。 【参考方案1】:

好的,从 cmets 看来,我似乎很清楚,根据您目前提供的信息,我们无法解决这个问题。我们能做的最好的就是提供有关如何调试它的建议......

我会尝试在其中一个尖峰期间使用jstack,看看您是否可以使用它来确定它挂在哪里。

【讨论】:

我以前没用过 jstack——它告诉你的不仅仅是一个简单的线程转储吗? @Alex 是的,确实如此。阅读文档 嗯,他是特意请教调试它的建议。【参考方案2】:

如果您没有机会在代码中测量或调试,请尝试从外部查看。

我首先会尝试重现该问题。换句话说,是否存在产生行为的外部事件。尝试更改服务器上的负载。尽可能切换一切以重现问题。

也许在服务器挂起时嗅探网络流量 (tcpdump) 以找到有趣的东西也是一个好主意。

您也可以在其他操作系统上运行它以检查它是否依赖于您的安装环境。

如果您无法重现出现问题的情况,请尝试找出您没有遇到问题的情况。例如从网络中删除服务器。关闭所有其他服务。

如果您无法发现程序行为的任何变化,请尝试降低工作代码的复杂性,并查看是否可以找到似乎与问题相关的内部模块。

【讨论】:

【参考方案3】:

您之前是否遇到过这个问题并已解决?或者你能指点我吗 可以弄清楚我的服务器在做什么的工具的方向 在YourKit不能的时候?

如果您在服务器上具有 shell 访问权限并且可以看到标准输出,请尝试在服务器无响应时进行线程转储。不确定这是否会给您带来与 jstack (在另一个答案中提到的)不同的东西。

在 Ubuntu 上:kill -QUIT <java-pid>(实际上不会杀死 Java 进程)。

http://www.crazysquirrel.com/computing/java/basics/java-thread-dump.jspx

【讨论】:

以上是关于当分析器无法收集样本时,如何调试无响应的服务器?的主要内容,如果未能解决你的问题,请参考以下文章

如何分析解决Android ANR

VS2015 只要调试时就卡死无响应,只能结束任务,怎么办求解

Windows Azure 角色无响应

aiohttp asyncio.TimeoutError 从无使用 ClientSession

如何解决 CameraX 应用程序无响应的问题?

加载大页面时 Internet Explorer 无响应