![性能不佳的 Java 应用程序与性能不佳的服务器](https://linux22.com/image/40068/%E6%80%A7%E8%83%BD%E4%B8%8D%E4%BD%B3%E7%9A%84%20Java%20%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E4%B8%8E%E6%80%A7%E8%83%BD%E4%B8%8D%E4%BD%B3%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%99%A8.png)
这是一个非常普遍的问题,但对我来说越来越频繁地出现。我想尝试为这种一般情况确定适当的行动方案,因为我认为这将来可以使我和其他系统管理员受益。但所有情况的共同点是 java。我在这里问这个问题而不是堆栈溢出的原因是这是一个系统管理员问题。我觉得放在这里是非常合适的。
一位用户走过来对我说:“我的应用程序非常慢。你给我的服务器性能很差。”该服务器可以是裸机、OpenVZ 或 KVM。在所有情况下,操作系统都是 CentOS 6。当用户告诉我这一点时,他们指的是页面加载时间 (JIRA) 或基准数字。 (Selenium 或专有应用程序)
现在,我偷偷怀疑服务器本身没有问题。我ssh
进入服务器,发现负载小于 1。内存使用情况也很好,空闲内存范围为 2-20 GB。最后,我检查iowait
,vmstat
发现它是 0。cpu 空闲是 99。
通过查看 Java top
,我可以看到该进程的 CPU 百分比约为 200% 左右。这是在具有 4 到 24 个内核的系统上。
当然,openvz
处理器分配与 KVM 或裸机不同吗?)如果这种情况发生在客户机上openvz
,kvm
我也会跳到主机上,并看到类似的情况。 CPU空闲率为99%。 iowait 为 0。内存有时有数百个空闲。
strace
我用、 和观察了这些 java 进程和线程strace -f
。有大量的 futex、clock 和epoll
.如果我反转 grep 这些,我剩下的大部分是 ioctl、stat、sendto。
发生这种情况的应用程序:Selenium、JIRA 和杂项专有 java 应用程序。不过总是java。
我考虑过调整 java 进程的良好性,但据我所知,良好性只会影响进程的调度方式。如果负载较低,则无助于加快速度。
有时应用程序使用 mysql,但查看顶部的 mysql 显示那里几乎没有 cpu 使用率。我猜如果这是瓶颈,我们会看到更高的 CPU 使用率。
底线:我如何向用户证明服务器工作正常,但他们的应用程序很糟糕?理论上,应用程序可能会很慢,因为它遇到了永远不会退出的 while 循环。这让我相信这项任务是不可能的,类似于解决停机问题。 o_O 但也许我可以调整 java 使其表现得更好一点,或者也许有一种方法可以分析正在运行的应用程序,指向一段代码并说“这就是你的问题”。
答案1
夏洛克!
一旦排除了不可能的事情,剩下的无论多么不可能,都一定是事实。 ——阿瑟·柯南·道尔
首先您可能想查看这talk,这是关于性能问题的根源以及如何诊断它们的讨论。它将 Linux 与 SmartOS 进行了比较,这与您的帖子的观点有些不同,但它也有助于阐明性能问题的根源。
通常,当您调试软件性能问题时,您应该尝试在单独的物理机器上复制完全相同的软件配置,具有相同的 Java 版本、相同的内核、相同的用户空间等。如果性能问题不存在,然后您可以开始查看物理硬件、虚拟机管理程序/容器层或您机器上的安装问题。
如果用户以前从未在该特定操作系统/版本配置中运行过该软件,那么他们无法立即声称这是您的服务器。我宁愿把举证责任放在他们为了证明,运行 CentOS 6(具有相同的次要版本、相同的虚拟机管理程序和相同的主机操作系统,如果它不是在裸机上运行),它们能够获得更好的性能。
如果性能更好,那么是因为他们拥有更优越的系统规格(例如,他们在基础设施的低端处理器上的 1 GB KVM 上运行它,但在他们自己的 24 核 Ivy Bridge E5 系统上运行,其中有 8 个 PCIe SSD硬件RAID0,速度快1000%),然后就可以开始谈论物理硬件了。如果物理硬件相同或非常相似,您可以开始讨论操作系统/管理程序配置。
您还可以考虑以下可能性:根据应用程序的性能以及用户数量和数据工作负载,为用户分配的硬件根本不足以完成该任务。如果这是一个非常重要的客户,并且让他们满意对您的业务至关重要,您可以尝试取消可能对其虚拟容器或 VM 实例施加的一些限制;例如,暂时给他们更多 RAM 或 CPU 时间、网络带宽等,看看是否有帮助。如果是这样,您可能必须告诉用户他们需要购买更大的虚拟机才能在该工作负载上获得他们想要的性能。
逃离困境(当这不是你的问题时)
如果出于某种原因,用户断然拒绝在单独的硬件上尝试相同的软件配置,您将不得不求助于帮助他们解决应用程序中的性能问题(正如 Brendan Gregg 所描述的,这在 Linux 上可能很难甚至不可能)在他的演讲中;有时你可能只需要“承受”性能成本),或者干脆坚持认为用户是不正确的。这是在系统上支持开发人员的一个不幸的副作用。
此时您可能需要问自己您与用户的业务关系是什么(如果有)。如果您提供不受管理的在私营部门托管,您可能必须坚持认为您不负责确保用户代码的性能。
如果您提供管理托管,或者以其他方式同意帮助软件人员解决他们的问题,无论问题是否是他们的错,您可能必须卷起袖子,亲自动手,并开始运行一些更复杂的性能分析工具,看看是否你可以发现实际的问题。它只是网络套接字上的一个非常闲聊的协议阻塞吗?是否受内存 I/O 限制?或者BIOS可能没有启用VT-x?有太多的可能性甚至无法列出。
总结一下本节:如果你能找到一些商业或政治上的理由来借口自己不负责解决这个问题,这可能是最简单、最有效的出路。不幸的是,这也意味着用户可能永远无法解决他们的问题,并且可能会寻求其他业务合作伙伴作为替代方案。
煽风点火(当这是你的问题时)
由于常见主题“似乎”是 Java,因此您至少可以首先确定 Java 进程本身是否正在运行一些非常慢的代码。为此,理想情况下,开发人员/用户/客户将能够向您提供其 Java 程序(以及所有依赖库)的源代码。
尝试在良好的环境下运行程序分析器。有免费和非免费的分析器;免费的一个例子是附带的网豆。让探查器成功启动和检测您的应用程序可能是一个挑战,具体取决于该应用程序是什么,但结果几乎总是在某种程度上说明问题。
当然,您可以使用htop
和/或iotop
检测 Java VM(或关联的 RDBMS)是否正在执行过多的 CPU、内存 I/O 或磁盘 I/O,超出了您考虑的数量“合理”(考虑到硬件和工作量)。这些都是极其宽泛的工具,并不总能为您提供全面的信息,因为有时性能问题与程序的内容有关不是在等待其他事情的同时做这件事,这可能与资源瓶颈无关。这与尝试启动汽车以确定发动机是否正常运行一样通用。如果它没有开始,那么,你该怎么办?这就是为什么如果您确实需要深入研究,合适的 Java 分析器会派上用场。
最后,我只是重复 Brendan Gregg 在他的演讲中所说的话,并提到 DTrace。 DTrace 的全部功能尚未在 Linux 上复制,无论是 dtrace-on-linux 重新实现,还是任何竞争对手(例如 SystemTap)。也就是说,你可以试图使用其中一种工具,看看是否有帮助。一些洞察力可以比没有任何。
当然,您需要特定的专业知识来使用这些非常“瑞士军刀”类型的工具。您将通过大量经验获得大部分专业知识(阅读:尝试和错误以及谷歌搜索)。这不仅仅是启动该工具并让它指出问题所在的问题;而是要解决的问题。您需要根据可用数据来解决问题。这并不容易。性能很少。