3

我在 Amazon EC2 微实例上的 JVM 中运行 Play Framework Scala 应用程序。该应用程序有时会索引大量文本。但是,如果虚拟机的 CPU 一直处于高负载状态,则管理程序会通过从虚拟机中窃取时间并将其提供给由该管理程序管理的其他虚拟机来惩罚虚拟机。

我正在考虑测量当前被盗的时间量,如果它太高(例如超过 5%),那么我将暂停索引一段时间。东西问题:

  1. 这是个好主意吗?(是疯了吗?还是有更好的方法?)

  2. 我如何测量从 Scala / Java 窃取的时间?

    目前我正在考虑进行外部流程调用(例如Seq("bash", "-c", "echo 日期")!!vmstat/proc/stat解析输出,并找到被盗的时间。但这可能容易出错?如果例如新版本的vmstat输出数据以另一种格式怎么办。我猜,但是, 的输出/proc/stat永远不会以非向后兼容的方式改变。(?)

所有这些都不需要在 Windows 上运行。仅限 Linux 版本,例如 Ubuntu 和 CentOS。如果外部进程调用失败,我会简单地返回 Scala 的None而不是Some(percentage).

更新:我找到了一个名为 Sigar 的库,它的功能getStolen可能合适。它返回一个double表示“总系统 cpu 非自愿等待时间”的值——但是以什么单位?我想知道它是否不幸的是自应用程序启动以来的总和。无论如何,这里有人实际使用它来打印被盗时间:https ://forums.oracle.com/thread/1301532

4

2 回答 2

2

我怀疑这些工具会支持虚拟机。

我建议定期轮询 System.nanoTime(),当你看到时间跳跃时,你的线程没有运行。您甚至可以执行类似 jHiccup 之类的操作,它只等待一毫秒并计算所花费的时间。

注意:即使虚拟机处于空闲状态,这也会显示非常糟糕的结果,因此您必须针对您的机器对其进行调整。

于 2013-08-11T12:47:15.037 回答
1

当 cpu 有多个核心时nanoTime,不会消耗 cpu。JVM 有一个工具MXBean,可以帮助确定实际的 cpu 使用情况。我认为mxBean.getCurrentThreadCpuTime()可以用于目的。至少你可以试试

@tailrec
def working {
  val startCpu = mxBean.getCurrentThreadCpuTime
  val startRealTime = System.nanoTime
  `do some work`
  val deltaCpu = mxBean.getCurrentThreadCpuTime - startCpu
  val deltaRealTime = System.nanoTime - startRealTime
  val percentage = 100.0*deltaCpu/deltaRealTime
  if(percentage>5.0) suspend else working
}
于 2013-08-13T17:34:12.577 回答