我在Amazon EC2微实例上的JVM中运行Play Framework Scala应用程序。应用程序有时会索引大量文本。但是,如果虚拟机的CPU始终处于高负载状态,则虚拟机管理程序会通过从虚拟机中窃取时间并将其提供给该虚拟机管理程序管理的其他虚拟机来惩罚虚拟机。
我正在考虑测量当前被盗的时间,如果它太高(超过例如5%),那么我会暂停索引一段时间。 东西 问题:
这是一个好主意吗? (这是疯了吗?还是有更好的方法?)
如何从Scala / Java中测量被盗时间?
目前我正在考虑进行外部流程调用(e.g. Seq("bash", "-c", "echo
date")!!
到vmstat
或/proc/stat
并解析输出,并发现时间被盗。但这可能容易出错?如果例如vmstat
的新版本以另一种格式输出数据会怎样。但我想,/proc/stat
的输出永远不会以非向后兼容的方式改变。(?)
所有这些都不需要在Windows上运行。只有Linux的风格,例如Ubuntu和CentOS。如果外部流程调用失败,我只需返回Scala的None
而不是Some(percentage)
。
更新:我找到了一个名为Sigar且可能适合a function getStolen
的库。它返回一个double
代表“总系统cpu非自愿等待时间” - 但是以什么单位?而且我不知道自应用程序启动以来它是否是一个累计总数。无论如何,这里有人用它来打印被盗时间:https://forums.oracle.com/thread/1301532
答案 0 :(得分:2)
我怀疑这些工具是否可以识别虚拟机。
我建议定期轮询System.nanoTime(),当你看到跳转时,你的线程没有运行。你甚至可以做像jHiccup这样的东西,等待一毫秒,然后花费多长时间。
注意:即使虚拟机的盒子空闲,这也会显示非常差的结果,因此您必须为您的机器调整它。
答案 1 :(得分: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
}