高CPU,可能是由于上下文切换?

Yon*_*Yon 6 java multithreading

我们的一台服务器在我们的应用程序中遇到了非常高的CPU负载.我们查看了各种统计数据,并且在找到问题根源时遇到了问题.

目前的理论之一是涉及太多线程,我们应该尝试减少并发执行线程的数量.只有一个主线程池,有3000个线程,还有一个使用它的WorkManager(这是Java EE - Glassfish).在任何给定时刻,需要并行执行大约620个单独的网络IO操作(也不能使用java.NIO).此外,大约有100个操作没有涉及IO,也是并行执行的.

这种结构效率不高,我们想看看它是否真的造成了损害,或者只是不好的做法.原因是在这个系统中任何变化都非常昂贵(就工时而言)所以我们需要一些问题的证据.

所以现在我们想知道线程的上下文切换是否是原因,因为线程比所需的并发操作多得多.查看日志,我们发现在给定的秒内平均执行了14个不同的线程.如果我们考虑到两个CPU的存在(见下文),则每个CPU有7个线程.这听起来不是太多,但我们想验证这一点.

那么 - 我们可以排除上下文切换或太多线程作为问题吗?

一般细节:

  1. Java 1.5(是的,它已经老了),运行在CentOS 5,64位Linux内核2.6.18-128.el5上
  2. 机器上只有一个Java进程,没有别的.
  3. 两个CPU,在VMware下.
  4. 8GB RAM
  5. 我们没有在机器上运行探查器的选项.
  6. 我们没有选择升级Java和OS.

更新 如下所述,我们在各种负载的测试服务器上进行了平均负载(使用正常运行时间)和CPU(使用vmstat 1 120)的捕获.我们在每次负载变化和测量之间等待15分钟,以确保系统在新负载周围稳定并且负载平均数更新:

50%的生产服务器工作负载:http://pastebin.com/GE2kGLkk

34%的生产服务器工作负载:http://pastebin.com/V2PWq8CG

25%的生产服务器工作负载:http://pastebin.com/0pxxK0Fu

随着负载的减少,CPU使用率似乎会降低,但不是非常激烈的水平(从50%变为25%并不是CPU使用率降低50%).负载平均值似乎与工作负载量无关.

还有一个问题:鉴于我们的测试服务器也是一个虚拟机,它的CPU测量是否会受到在同一主机上运行的其他虚拟机的影响(使上述测量无用)?

更新2 以三个部分附加线程的快照(pastebin限制)

第1部分:http://pastebin.com/DvNzkB5z

第2部分:http://pastebin.com/72sC00rc

第3部分:http://pastebin.com/YTG9hgF5

Wil*_*ung 5

在我看来,问题在于 100 个 CPU 绑定线程比其他任何事情都多。3000 个线程池基本上是一个转移注意力的东西,因为空闲线程不会消耗太多东西。I/O 线程可能“大部分”时间处于休眠状态,因为 I/O 是根据计算机操作的地质时间尺度来测量的。

你没有提到 100 个 CPU 线程正在做什么,或者它们持续了多长时间,但如果你想减慢计算机的速度,专用 100 个线程“运行直到时间片说停止”肯定会做到这一点。因为你有 100 个“随时准备运行”,所以机器将按照调度程序允许的速度进行上下文切换。空闲时间几乎为零。上下文切换会产生影响,因为您经常这样做。由于 CPU 线程(可能)消耗了大部分 CPU 时间,因此 I/O“绑定”线程在运行队列中等待的时间将比等待 I/O 的时间长。因此,更多的进程正在等待(I/O 进程只是更频繁地退出,因为它们很快遇到 I/O 障碍,从而使进程空闲下来等待下一个进程)。

毫无疑问,为了提高效率,这里和那里都有一些调整,但 100 个 CPU 线程就是 100 个 CPU 线程。你在那里无能为力。